Grades are a hygiene check, not a security guarantee.

MCP, MCP server

memorycrystal

To get memorycrystal on Windows, visit the release page and download the latest file from there:

Compatibility: Not stated.

Grade C

One Medium finding. Read the report before installing.

Graded by PlugVetRubric v2

Not a guarantee. A hygiene check of the source at the commit shown, not a security audit.

INSTALL_REMOTE_SCRIPT

Why this grade

  • INSTALL_REMOTE_SCRIPT Medium

    Fetches a script from the network and runs it (a pipe to a shell, or an install hook with a URL).

    scripts/install-openclaw.sh, line 264 echo " curl -fsSL $MIGRATE_URL | bash -s -- --api-key <key>"

Any High, or two or more Medium findings, give D. One Medium gives C. Low findings or a security Note give B. Each code names a finding behind the letter.

Grades are a hygiene check of the source at the commit shown, on the date checked, not a security audit or a guarantee. The free directory grades are automated. Before release, a PlugVet engineer reviews every paid report and any grade we hold back, including all F grades, against the source code and the evidence we quote.

What was checked

Plain notes from the hygiene checks.

  • Permissions

    Concern

    can delete files.

    PERMISSION_DELETE_FILES

    plugin/capture-hook.js, line 5

    * It was previously used by handler.js (via child_process.spawnSync) and as a

    plugin/index.test.js, line 624

    fs.rmSync(dbPath, { force: true });

    plugin/index.test.js, line 696

    fs.rmSync(dbPath, { force: true });

    Show more

    plugin/index.test.js, line 736

    fs.rmSync(dbPath, { force: true });

    plugin/index.test.js, line 766

    fs.rmSync(dbPath, { force: true });

    plugin/index.test.js, line 806

    fs.rmSync(dbPath, { force: true });

    plugin/index.test.js, line 860

    fs.rmSync(dbPath, { force: true });

    plugin/index.test.js, line 1197

    fs.rmSync(dbPath, { force: true });

    scripts/crystal-doctor.sh, line 517

    cm_entry = commands.get("crystal-memory")

    scripts/crystal-doctor.sh, line 527

    cc_entry = commands.get("crystal-capture")

    scripts/crystal-doctor.sh, line 535

    cr_entry = commands.get("crystal-recall")

  • Install and update

    Serious

    install fetches a script from the network. The docs document an installer that pipes a download into a shell.

    INSTALL_REMOTE_SCRIPT INSTALL_DOCUMENTED_INSTALLER

    plugin/README.md, line 8

    curl -fsSL https://memorycrystal.ai/crystal | bash

    scripts/install-openclaw.sh, line 264

    echo " curl -fsSL $MIGRATE_URL | bash -s -- --api-key <key>"

    scripts/install-openclaw.sh, line 271

    echo " curl -fsSL $MIGRATE_URL | bash -s -- --api-key <key>"

    Show more

    apps/docs/concepts/how-memory-works.mdx, line 68

    curl -fsSL https://memorycrystal.ai/crystal | bash

    apps/docs/help/uninstall.mdx, line 19

    curl -fsSL https://memorycrystal.ai/uninstall.sh | bash

    apps/docs/help/uninstall.mdx, line 25

    curl -fsSL https://memorycrystal.ai/uninstall.sh | bash -s -- --purge

    apps/docs/help/uninstall.mdx, line 40

    curl -fsSL https://memorycrystal.ai/uninstall-claude-mcp.sh | bash

    apps/docs/help/uninstall.mdx, line 46

    curl -fsSL https://memorycrystal.ai/uninstall-claude-mcp.sh | bash -s -- --purge

    apps/docs/help/uninstall.mdx, line 60

    curl -fsSL https://memorycrystal.ai/uninstall-codex-mcp.sh | bash

    apps/docs/help/uninstall.mdx, line 66

    curl -fsSL https://memorycrystal.ai/uninstall-codex-mcp.sh | bash -s -- --purge

    apps/docs/help/uninstall.mdx, line 80

    curl -fsSL https://memorycrystal.ai/uninstall-droid-mcp.sh | bash

    apps/docs/help/uninstall.mdx, line 86

    curl -fsSL https://memorycrystal.ai/uninstall-droid-mcp.sh | bash -s -- --purge

    apps/docs/installation.mdx, line 98

    curl -fsSL https://memorycrystal.ai/crystal | bash

    apps/docs/integrations/claude-code.mdx, line 37

    curl -fsSL https://memorycrystal.ai/install-claude-mcp.sh | bash

    apps/docs/integrations/claude-code.mdx, line 49

    curl -fsSL https://memorycrystal.ai/uninstall-claude-mcp.sh | bash

    apps/docs/integrations/codex-cli.mdx, line 36

    curl -fsSL https://memorycrystal.ai/install-codex-mcp.sh | bash

    apps/docs/integrations/codex-cli.mdx, line 48

    curl -fsSL https://memorycrystal.ai/uninstall-codex-mcp.sh | bash

    apps/docs/integrations/factory-droid.mdx, line 34

    curl -fsSL https://memorycrystal.ai/install-droid-mcp.sh | bash

    apps/docs/integrations/factory-droid.mdx, line 40

    curl -fsSL https://memorycrystal.ai/uninstall-droid-mcp.sh | bash

    apps/docs/integrations/openclaw-plugin.mdx, line 24

    curl -fsSL https://memorycrystal.ai/crystal | bash

    apps/docs/integrations/openclaw-plugin.mdx, line 70

    curl -fsSL https://memorycrystal.ai/uninstall.sh | bash

    apps/docs/introduction.mdx, line 63

    curl -fsSL https://memorycrystal.ai/crystal | bash

    apps/docs/quickstart.mdx, line 13

    curl -fsSL https://memorycrystal.ai/crystal | bash

    apps/docs/quickstart.mdx, line 19

    curl -fsSL https://memorycrystal.ai/install-claude-mcp.sh | bash

    apps/docs/quickstart.mdx, line 25

    curl -fsSL https://memorycrystal.ai/install-codex-mcp.sh | bash

    apps/docs/quickstart.mdx, line 31

    curl -fsSL https://memorycrystal.ai/install-droid-mcp.sh | bash

  • Network

    Concern

    can reach a host that is not written as a fixed address. can reach api.openai.com. The description does not name that host. can reach api.anthropic.com. The description does not name that host. can reach api.memorycrystal.ai. The description does not name that host.

    NETWORK_NO_FIXED_HOST NETWORK_UNNAMED_HOST

    convex/crystal/assets.ts, line 54

    const response = await fetch(

    convex/crystal/assets.ts, line 94

    const fileResponse = await fetch(asset.storageKey);

    convex/crystal/assets.ts, line 116

    const response = await fetch(

    Show more

    convex/crystal/graphEnrich.ts, line 490

    const response = await fetch(

    convex/crystal/knowledgeBases.ts, line 1654

    const response = await fetch(

    convex/crystal/knowledgeBases.ts, line 1686

    const response = await fetch(

    convex/crystal/mcp.ts, line 459

    const response = await fetch(

    convex/crystal/messages.ts, line 570

    // Apply sinceMs filter post-fetch (not a valid vector filterField)

  • Secrets

    Concern

    reads a credential or environment file.

    SECRETS_ENV_READ SECRETS_PATH_DOTENV

    convex/crystal/assets.ts, line 155

    const apiKey = process.env.CRYSTAL_API_KEY ?? process.env.GEMINI_API_KEY;

    convex/crystal/contentScanner.ts, line 31

    // 'cat .env' only when combined with exfiltration (pipe to curl/wget/send/post)

    convex/crystal/contentScanner.ts, line 32

    /cat\s+(?:\/[\w./]*)?\.env\b.*\|\s*(?:curl|wget|nc|sendmail)/i,

    Show more

    convex/crystal/contentScanner.ts, line 33

    /cat\s+(?:\/[\w./]*)?\.env\b.*(?:send|post|upload)\b/i,

    convex/crystal/graphEnrich.ts, line 473

    const apiKey = process.env.CRYSTAL_API_KEY ?? process.env.GEMINI_API_KEY;

    convex/crystal/knowledgeBases.ts, line 412

    return Boolean(process.env.CRYSTAL_API_KEY ?? process.env.GEMINI_API_KEY);

    convex/crystal/knowledgeBases.ts, line 1650

    const apiKey = process.env.CRYSTAL_API_KEY ?? process.env.GEMINI_API_KEY;

    convex/crystal/knowledgeBases.ts, line 1681

    const apiKey = process.env.CRYSTAL_API_KEY ?? process.env.GEMINI_API_KEY;

    convex/crystal/mcp.ts, line 450

    const apiKey = process.env.CRYSTAL_API_KEY ?? process.env.GEMINI_API_KEY;

    convex/crystal/mcp.ts, line 1998

    const openaiApiKey = process.env.OPENAI_API_KEY;

    convex/crystal/mcp.ts, line 2271

    if (!(process.env.CRYSTAL_API_KEY ?? process.env.GEMINI_API_KEY)) return { processed: 0, succeeded: 0, done: true };

    plugin/recall-hook.js, line 34

    path.resolve(__dirname, "..", "mcp-server", ".env"),

    scripts/crystal-doctor.sh, line 152

    ".env.example"

    scripts/crystal-doctor.sh, line 210

    ENV_FILE="$REPO_ROOT/mcp-server/.env"

    scripts/crystal-doctor.sh, line 212

    ENV_FILE="$REPO_ROOT/.env"

    scripts/crystal-doctor.sh, line 307

    warn "No .env file found at $REPO_ROOT/mcp-server/.env or $REPO_ROOT/.env"

  • Agent instructions

    Pass

    No instruction to ignore earlier instructions or to hide a step.

  • Obfuscation

    Note

    a file was over the read cap and was not fully read.

    OBFUSCATION_FILE_OVER_READ_CAP

    package-lock.json, line 1

    {

  • Licence

    Pass

    A licence file is present (LICENSE).

  • Maintainer activity

    Pass

    The latest commit is within the last 365 days.

Note

Hygiene check of commit 1519d54b9f56. can delete files. install fetches a script from the network. The docs document an installer that pipes a download into a shell. can reach a host that is not written as a fixed address. can reach api.openai.com. The description does not name that host. can reach api.anthropic.com. The description does not name that host. can reach api.memorycrystal.ai. The description does not name that host. reads a credential or environment file. a file was over the read cap and was not fully read.

Date and source

Date checked:

View source

github.com

Commit graded: 1519d54b9f56259bfbafa3c128619694709375e1

This link goes to the original host. PlugVet does not host or check what you download from there, and installing it is your own decision and risk.

Read how this letter is chosen