Grades are a hygiene check, not a security guarantee.

MCP, MCP server

Openchronicle Mcp

Openchronicle Mcp, an MCP server listed in the PlugVet directory.

Compatibility: Not stated.

Grade B

Minor issues only, no Medium or High. Worth a quick look at the findings below before installing.

Graded by PlugVetRubric v2

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

Rescanned at commit bc0658e565f7, unchanged since the check below.

PERMISSION_DELETE_FILES NETWORK_NO_FIXED_HOST NETWORK_UNNAMED_HOST SECRETS_PATH_DOTENV SECRETS_ENV_READ OBFUSCATION_FILE_OVER_READ_CAP

Why this grade

  • PERMISSION_DELETE_FILES Low

    Contains a call that can delete files.

    .codex/hooks/post_compact_reload.py, line 35 completed = subprocess.run(

  • NETWORK_NO_FIXED_HOST Low

    Makes a network call whose host is not written as a fixed address.

    scripts/smoke_test.py, line 47 with urllib.request.urlopen(req, timeout=timeout) as resp: # noqa: S310

  • NETWORK_UNNAMED_HOST Low

    Calls a fixed host that the description does not name.

    scripts/smoke_test.py, line 47 with urllib.request.urlopen(req, timeout=timeout) as resp: # noqa: S310

  • SECRETS_PATH_DOTENV Low

    Mentions a .env file.

    scripts/env_vault.py, line 4 application logs: the operator fills the gitignored ``.env`` by hand,

  • SECRETS_ENV_READ Note

    Reads an environment variable whose name contains KEY, SECRET, TOKEN, PASSWORD or CREDENTIAL.

    scripts/benchmark_embeddings.py, line 418 if not os.getenv("OPENAI_API_KEY"):

  • OBFUSCATION_FILE_OVER_READ_CAP Note

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

    uv.lock, line 1 version = 1

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

    .codex/hooks/post_compact_reload.py, line 35

    completed = subprocess.run(

    scripts/offline_restore.py, line 410

    shutil.rmtree(scratch, ignore_errors=True)

    scripts/probe_performance.py, line 1478

    process = subprocess.Popen(

    Show more

    scripts/probe_performance.py, line 1536

    def _wait_for_health(base_url: str, timeout_seconds: float, process: subprocess.Popen[bytes]) -> int:

    scripts/probe_performance.py, line 1667

    def _terminate_matrix_process(process: subprocess.Popen[bytes]) -> None:

    scripts/probe_performance.py, line 1673

    subprocess.run(

    scripts/probe_performance.py, line 1696

    processes: dict[str, subprocess.Popen[bytes]] = {}

    scripts/probe_performance.py, line 1749

    processes[label] = subprocess.Popen(

    scripts/probe_performance.py, line 1829

    commit = subprocess.check_output(

    src/openchronicle/core/infrastructure/maintenance/jobs.py, line 273

    shutil.rmtree(entry, ignore_errors=True)

    tools/perf/meas01.py, line 518

    shutil.rmtree(work, ignore_errors=True)

  • Install and update

    Pass

    No install-time script found, and dependencies are pinned or absent.

  • Network

    Concern

    can reach a host that is not written as a fixed address. can reach codeload.github.com. The description does not name that host.

    NETWORK_NO_FIXED_HOST NETWORK_UNNAMED_HOST

    scripts/smoke_test.py, line 47

    with urllib.request.urlopen(req, timeout=timeout) as resp: # noqa: S310

    scripts/smoke_test.py, line 198

    with urllib.request.urlopen(req, timeout=10) as resp: # noqa: S310

    src/openchronicle/core/infrastructure/embedding/ollama_adapter.py, line 130

    response = httpx.post(url, json=body, timeout=self._timeout, verify=self._verify_tls)

    Show more

    src/openchronicle/core/infrastructure/embedding/ollama_adapter.py, line 243

    response = httpx.get(url, timeout=_PROBE_TIMEOUT, verify=self._verify_tls)

    tools/backup-drill/drill-nas.sh, line 117

    h = json.load(urllib.request.urlopen("http://127.0.0.1:8000/api/v1/health", timeout=10))

    tools/backup-drill/drill-nas.sh, line 118

    s = json.load(urllib.request.urlopen("http://127.0.0.1:8000/api/v1/memory/search?query=backup&mode=keyword&top_k=3", timeout=10))

    tools/backup-drill/probe.py, line 31

    with urllib.request.urlopen(BASE + path, timeout=10) as response:

    tools/backup-drill/ts03-rehearsal.sh, line 193

    curl -fsSL "https://codeload.github.com/CarlDog/openchronicle-mcp/tar.gz/$NEW_SHA" | tar -xz -C "$WORK"

    tools/ci/smoke-image.sh, line 46

    with urllib.request.urlopen(base + "/health", timeout=3) as response:

    tools/ci/smoke-image.sh, line 48

    with urllib.request.urlopen(base + "/api/v1/health", timeout=3) as response:

    Dockerfile, line 111

    CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8000/health',timeout=3).status==200 else 1)"

    docker-compose.nas.yml, line 202

    'python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen(''http://127.0.0.1:8000/health'',timeout=3).status==200 else 1)"',

    docker-compose.phase4-test.yml, line 52

    'python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen(''http://127.0.0.1:8000/health'',timeout=3).status==200 else 1)"',

  • Secrets

    Concern

    reads a credential or environment file.

    SECRETS_ENV_READ SECRETS_PATH_DOTENV

    scripts/benchmark_embeddings.py, line 418

    if not os.getenv("OPENAI_API_KEY"):

    scripts/env_vault.py, line 4

    application logs: the operator fills the gitignored ``.env`` by hand,

    scripts/env_vault.py, line 5

    ``encrypt`` turns it into ``.env.dpapi`` (Windows DPAPI, CurrentUser

    Show more

    scripts/env_vault.py, line 12

    python scripts/env_vault.py encrypt # .env -> .env.dpapi, shred .env

    scripts/env_vault.py, line 25

    PLAIN_PATH = ROOT / ".env"

    scripts/env_vault.py, line 26

    VAULT_PATH = ROOT / ".env.dpapi"

    scripts/env_vault.py, line 71

    raise SystemExit("no non-empty entries in .env - fill in values first")

    scripts/env_vault.py, line 89

    print(f"vault written: {VAULT_PATH.name} ({len(entries)} keys) - plaintext .env shredded")

    scripts/env_vault.py, line 114

    print("no vault (.env.dpapi missing)")

    src/openchronicle/core/application/services/git_onboard.py, line 687

    token = os.environ.get("OC_GIT_TOKEN")

    src/openchronicle/core/application/services/git_onboard.py, line 709

    secrets = [os.environ.get("OC_GIT_TOKEN") or ""]

    src/openchronicle/core/infrastructure/embedding/openai_adapter.py, line 77

    self._api_key = api_key or os.getenv("OPENAI_API_KEY") or None

    src/openchronicle/interfaces/api/config.py, line 58

    api_key = (os.environ.get("OC_API_KEY", "").strip() or str_or_default(fc.get("api_key"), "")) or None

  • 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

    uv.lock, line 1

    version = 1

    docs/CODEBASE_ASSESSMENT.md, line 1

    # OpenChronicle - Codebase Assessment

  • 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 bc0658e565f7. can delete files. can reach a host that is not written as a fixed address. can reach codeload.github.com. 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: bc0658e565f7b55a32f049c0649495fcb5214c53

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