Announcing Beacon: Self-improving memory for coding agents
← All MCP servers
MCP server

io.github.yamantaka520/agent-memory-os

mcp:yamantaka520/agent-memory-os

Local-first memory engine for AI-agent teams: team/project ACL, recall, and federated sync.

Verdict
No issues found

Nothing found that works against the person who installs it.

Analyzed Oct 29, 2026, 15:49 UTC at 2932382

Dispute security verdict

If you believe this verdict is incorrect, submit a dispute and we'll review it.

0
findings
—
highest severity
0
threat classes
248
files scanned
606/606
checks satisfied
0
package advisories

Why this verdict

  • benign: 606 checks satisfied, nothing works against the installer of mcp-server:. (16 notes, 0 third-party flags)

Security findings 0

No security findings

Nothing found that works against the person who installs it.

Notes 16

Capabilities, vulnerabilities and disclosed behavior worth knowing. Nothing here works against the person who installs it, so notes never change the verdict.

Persistence

mediumNoteConfirmed on reviewhigh confidence

The path install command, run by the user, appends an export line to the user's zsh/fish/bash profile; this is disclosed in the command's help and is a user-invoked step.

rc = Path("~/.zshrc").expanduser()
vector:code
Reviewer's reasoning

The path install step appends an export line to the shell profile only when the user runs 'path install', which its help text discloses. It is a user-invoked step.

Persistence

mediumNoteConfirmed on reviewhigh confidence

The service install command, run by the user, installs a unit that starts the console at login; the command discloses this in its output.

installed — console at http://{host}:{port}/ (starts at login)
vector:code
Reviewer's reasoning

The service install is run by the user and its output discloses that the console starts at login. This is a user-invoked step with a disclosed effect.

Persistence

mediumNoteConfirmed on reviewlow confidence

The save_config method writes the user's chosen memory configuration into agent-memory-os.json under the Hermes home, an undeclared but setup-driven write that the user triggers through hermes memory setup.

path.write_text(json.dumps(current, indent=2) + "\n", encoding="utf-8")
vector:code
Reviewer's reasoning

save_config writes the user's own chosen settings into a config file under the Hermes home, and it runs only when the user goes through Hermes setup. This is a user-driven, setup-scoped write.

Persistence

mediumNoteConfirmed on reviewmedium confidence

The install_shim function writes a plugin shim into the Hermes plugins directory, a control-plane location, but only when the user runs the agent-memory hermes install command.

(target / "__init__.py").write_text(_SHIM_INIT, encoding="utf-8")
vector:code
Reviewer's reasoning

The shim is written only when the user runs the 'hermes install' command. It is a user-invoked, disclosed plugin registration.

Data exfiltration

mediumNoteConfirmed on reviewmedium confidence

join_with_code sends this node's sync token inside the encrypted envelope to the peer URL the user passes to the join command; the credential goes to a service the user directs it to, so it is a note.

"sync_token": own_sync_token,
vector:code
Reviewer's reasoning

The sync token goes only to the peer URL the user passes to the join command, and that user chose the host. This is a credential sent to a host the user directed it to, so it is not abuse.

Persistence

mediumNoteConfirmed on reviewmedium confidence

The service installer writes a per-user LaunchAgent or systemd unit that relaunches the web console at login; the user runs this install step, and the unit is the declared purpose, so it is an undeclared-but-documented persistence note.

path.write_text(render_launchd_plist(config))
vector:code
Reviewer's reasoning

The service installer writes a login unit only when the user runs the install step, and the unit is the declared console-service purpose. It is a user-invoked, disclosed step.

Data exfiltration

mediumNoteConfirmed on reviewmedium confidence

sync push_to_peer exports the local memory bundle and POSTs it to a registered peer URL; this is the declared mesh sync feature, with the scope set by the peer policy, so it is a disclosed note.

response = _http(base_url.rstrip("/") + "/api/sync/import", token=peer_token, post=payload)
vector:code
Reviewer's reasoning

The bundle is pushed only to a peer the user registered, and the scope is set by the peer policy. This is the declared mesh sync feature and a user-directed destination.

Credential access

mediumNoteConfirmed on reviewmedium confidence

_http attaches the peer bearer token to requests for any http:// peer URL, so a peer token travels in plaintext over HTTP; this is a hygiene weakness the user opts into when registering the peer.

request.add_header("Authorization", f"Bearer {token}")
vector:code
Reviewer's reasoning

The bearer token is attached to any http:// peer URL the user registered, so the credential goes to a host the user chose. Sending it in plaintext is a hygiene weakness, not abuse.

Supply chain

lowNoteConfirmed on reviewmedium confidence

The Smithery launch command runs 'uv run --with agent-memory-os[mcp]', fetching the publisher's own PyPI package unpinned at launch; this is a note because it is the publisher's package and the user's client starts it.

'--with', 'agent-memory-os[mcp]'
vector:code
Reviewer's reasoning

The Smithery launch fetches the publisher's own PyPI package unpinned when the user's client starts the server, which is the publisher's own launch path and a carve-out under test 5. Nothing steers the agent against the user.

Supply chain

lowNoteConfirmed on reviewhigh confidence

The update command runs pip install -U of the publisher's own agent-memory-os package with an unpinned version after user confirmation; this is a note on an unpinned install of the publisher's package.

cmd = [sys.executable, "-m", "pip", "install", "-U", "agent-memory-os[full]"]
vector:code
Reviewer's reasoning

The update command installs the publisher's own package only after the user is prompted unless --yes is passed, so the user opts into the step. This is an unpinned install of the publisher's own package, which is a note.

Privilege escalation

lowNoteConfirmed on reviewmedium confidence

The team rename CLI exposes a --yes flag that skips the confirmation prompt; it is a user-invoked option and is noted only, not an agent-driven bypass.

rename: skip the confirmation prompt
vector:code
Reviewer's reasoning

The --yes flag on team rename is a user-invoked option described in its help text, so the user decides to skip the prompt. The agent is not steered to do so.

Privilege escalation

lowNoteConfirmed on reviewmedium confidence

The update --team flag makes the artifact send the sync token to every opted-in peer to trigger a remote self-update of agent-memory-os; the user invokes this and the peer must opt in.

url.rstrip("/") + "/api/maintenance/update-run?confirm=update",
vector:code
Reviewer's reasoning

The team update is user-invoked via the --team flag, and each peer must opt in with AGENT_MEMORY_ALLOW_TEAM_UPDATE=1 before it acts. The peer update is the artifact's own update path, so it is a note under the carve-outs and test 4.

Privilege escalation

lowNoteConfirmed on reviewmedium confidence

The fleet console POSTs a self-update with a supplied confirm token to every managed node, which upgrades agent-memory-os and restarts each node; the user triggers this explicitly and the nodes' operators opted in by granting manage.

/api/maintenance/update-run?confirm=update
Reviewer's reasoning

The fleet update is triggered explicitly by the fleet admin who holds the console key, and each node is granted manage by its operator. The user invokes it, so it is a note under test 4.

Supply chain

lowNoteConfirmed on reviewmedium confidence

The fleet console's trigger_on sends an update action to peer nodes that makes each node upgrade itself and restart; the update is gated by the operator's manage grant, so it is a disclosed note-level self-update of the publisher's own product.

itself and restarts; each node's operator opted in by granting 'manage').
vector:code
Reviewer's reasoning

The update action is run only when the fleet admin triggers it, and it is gated by each node's operator granting manage. The self-update is the publisher's own product and is disclosed in the code comments.

Supply chain

lowNoteConfirmed on reviewmedium confidence

systemd_self_update runs pip to upgrade the publisher's own package unpinned, then restarts itself; this is the artifact's own update path and is a note.

"pip", "install", "--upgrade", "agent-memory-os"
vector:code
Reviewer's reasoning

systemd_self_update upgrades the publisher's own package from the update path the user invokes, and the carve-out covers the artifact's own update path. It is not a bypass of consent.

Supply chain

lowNoteConfirmed on reviewmedium confidence

A peer holding the sync token can trigger this node's self-update from the package index and restart it when the operator has opted in; this is an update of the artifact's own code and is noted only.

Team-wide updates: a peer's sync token may trigger THIS
Decoded
# Team-wide updates: a peer's sync token may trigger THIS node's self-update only when the operator opted in.
trigger:conditionalvector:code
Reviewer's reasoning

The peer-triggered update is gated on the operator setting AGENT_MEMORY_ALLOW_TEAM_UPDATE, and the update_run path upgrades the artifact's own package and restarts its own console, which is the self-update carve-out in test 5. The claim matches the code, so the finding stays a note.

Coverage gaps 1

Parts of the artifact the static analysis could not fully examine.

context:manifest_unparseable yaml: YAML aliases are not permitted
docker-compose.mesh.yml