Grades are a hygiene check, not a security guarantee.

MCP, MCP server

Bilinc

Bilinc, 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.

PERMISSION_DELETE_FILES NETWORK_NO_FIXED_HOST SECRETS_PATH_DOTENV SECRETS_ENV_READ

Why this grade

  • PERMISSION_DELETE_FILES Low

    Contains a call that can delete files.

    benchmarks/modal/amb_graph_candidate_runner.py, line 123 process = subprocess.run(command, cwd="/opt/amb", capture_output=True, text=True, check=False)

  • NETWORK_NO_FIXED_HOST Low

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

    scripts/prewarm_pg_tenants.py, line 30 rows = await conn.fetch(

  • SECRETS_PATH_DOTENV Low

    Mentions a .env file.

    benchmarks/modal/amb_graph_candidate_runner.py, line 48 if name.startswith(".env") or name.endswith((".sqlite", ".sqlite3", ".db", ".pem", ".key")):

  • SECRETS_ENV_READ Note

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

    src/bilinc/client.py, line 525 self.api_key = os.environ.get("BILINC_API_KEY") or load_config_api_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

    benchmarks/modal/amb_graph_candidate_runner.py, line 123

    process = subprocess.run(command, cwd="/opt/amb", capture_output=True, text=True, check=False)

    benchmarks/modal/amb_graph_candidate_runner.py, line 171

    "node": subprocess.run(

    benchmarks/modal/amb_runner.py, line 125

    process = subprocess.run(command, cwd="/opt/amb", capture_output=True, text=True, check=False)

    Show more

    benchmarks/modal/amb_runner.py, line 134

    "node": subprocess.run(["node", "--version"], capture_output=True, text=True, check=False).stdout.strip(),

    benchmarks/modal/amb_semantic_candidate_runner.py, line 198

    process = subprocess.run(command, cwd="/opt/amb", capture_output=True, text=True, check=False)

    benchmarks/modal/amb_semantic_candidate_runner.py, line 248

    "node": subprocess.run(

    benchmarks/modal/amb_temporal_intent_candidate_runner.py, line 131

    process = subprocess.run(command, cwd="/opt/amb", capture_output=True, text=True, check=False)

    benchmarks/modal/amb_temporal_intent_candidate_runner.py, line 178

    "node": subprocess.run(["node", "--version"], capture_output=True, text=True, check=False).stdout.strip(),

    src/bilinc/cloud/runtime.py, line 1237

    shutil.rmtree(directory)

  • 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.

    NETWORK_NO_FIXED_HOST

    scripts/prewarm_pg_tenants.py, line 30

    rows = await conn.fetch(

    src/bilinc/client.py, line 392

    system browser and curl can reach bilinc.space. certifi gives the public SDK

    src/bilinc/client.py, line 478

    with urllib.request.urlopen( # noqa: S310 - configured endpoint

    Show more

    src/bilinc/core/postgres_audit.py, line 109

    rows = await conn.fetch("SELECT * FROM audit_log ORDER BY id ASC")

    src/bilinc/core/vector_search.py, line 51

    resp = urllib.request.urlopen(req, timeout=10)

    src/bilinc/embeddings/encoder.py, line 157

    with urllib.request.urlopen(request, timeout=timeout, context=self._context) as response:

    src/bilinc/storage/postgres.py, line 385

    for row in await conn.fetch(

    src/bilinc/storage/postgres.py, line 495

    rows = await self.pool.fetch(sql, *params)

  • Secrets

    Concern

    reads a credential or environment file.

    SECRETS_ENV_READ SECRETS_PATH_DOTENV

    benchmarks/modal/amb_graph_candidate_runner.py, line 48

    if name.startswith(".env") or name.endswith((".sqlite", ".sqlite3", ".db", ".pem", ".key")):

    benchmarks/modal/amb_runner.py, line 57

    if name.startswith(".env") or name.endswith((".sqlite", ".sqlite3", ".db", ".pem", ".key")):

    src/bilinc/client.py, line 525

    self.api_key = os.environ.get("BILINC_API_KEY") or load_config_api_key()

    Show more

    benchmarks/modal/amb_semantic_candidate_runner.py, line 64

    if name.startswith(".env") or name.endswith((".sqlite", ".sqlite3", ".db", ".pem", ".key")):

    benchmarks/modal/amb_temporal_intent_candidate_runner.py, line 48

    if name.startswith(".env") or name.endswith((".sqlite", ".sqlite3", ".db", ".pem", ".key")):

    benchmarks/modal/locomo_runner.py, line 53

    if name.startswith(".env") or name.endswith((".sqlite", ".sqlite3", ".db", ".pem", ".key")):

    benchmarks/modal/locomo_semantic_candidate_runner.py, line 69

    if name.startswith(".env") or name.endswith((".sqlite", ".sqlite3", ".db", ".pem", ".key")):

    benchmarks/modal/locomo_temporal_intent_candidate_runner.py, line 52

    if name.startswith(".env") or name.endswith((".sqlite", ".sqlite3", ".db", ".pem", ".key")):

    src/bilinc/cli/main.py, line 177

    return bool(args.api_key or os.environ.get("BILINC_API_KEY") or load_config_api_key())

    src/bilinc/cloud/service.py, line 207

    expected_token = sidecar_token or os.getenv("BILINC_CLOUD_SIDECAR_TOKEN")

    src/bilinc/embeddings/encoder.py, line 118

    path = Path(token_file or os.environ.get("BILINC_CF_AI_TOKEN_FILE") or WORKERS_AI_TOKEN_FILE).expanduser()

    src/bilinc/mcp_server/hermes_stdio.py, line 28

    auth_token = os.getenv("BILINC_MCP_AUTH_TOKEN")

    src/bilinc/mcp_server/hermes_stdio.py, line 29

    max_tokens = int(os.getenv("BILINC_RATE_LIMIT_MAX_TOKENS", "10"))

    src/bilinc/mcp_server/server_v2.py, line 97

    return auth_token or os.environ.get("BILINC_MCP_AUTH_TOKEN")

    src/bilinc/security/secret_scan.py, line 98

    return os.getenv("BILINC_SECRET_SCAN", "on").strip().lower() not in {"off", "0", "false", "no"}

    .gitignore, line 37

    # Local env files

  • Agent instructions

    Pass

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

  • Obfuscation

    Pass

    No encoded or minified payload found.

  • 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 5578d273b6e6. can delete files. can reach a host that is not written as a fixed address. reads a credential or environment file.

Date and source

Date checked:

View source

github.com

Commit graded: 5578d273b6e63a300e2f775ff9c958ff56432ad7

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