MCP, MCP server
Pal Mcp Server
Pal Mcp Server, an MCP server listed in the PlugVet directory.
Compatibility: Not stated.
Grade D
Two or more Medium findings, or a High. Only try it in a sandbox.
Not a guarantee. A hygiene check of the source at the commit shown, not a security audit.
INSTALL_REMOTE_SCRIPT NETWORK_HOST_FROM_INPUT
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).
run-server.sh, line 341
echo " curl https://pyenv.run | bash" >&2 - NETWORK_HOST_FROM_INPUT Medium
A file takes a URL or endpoint as input and has no fixed host list.
run-server.sh, line 538
# Try curl first
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.
If you think this grade is wrong, email [email protected] with the entry link and your evidence. We aim to acknowledge within two working days and decide within seven. If we confirm an error, we aim to correct it within 24 hours of confirming it. These are aims, not guarantees.
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
communication_simulator_test.py, line 401
shutil.rmtree(self.temp_dir)
communication_simulator_test.py, line 412
return subprocess.run(cmd, check=check, capture_output=capture_output, **kwargs)
run-server.ps1, line 375
$null = Invoke-Expression "$cmd --version" 2>$null
Show more
run-server.ps1, line 583
Invoke-Expression "$pythonCmd -m venv $VENV_PATH"
run-server.ps1, line 653
Invoke-Expression "$pythonCmd -m venv $VENV_PATH"
docker/scripts/healthcheck.py, line 25
result = subprocess.run(["pgrep", "-f", "server.py"], capture_output=True, text=True, timeout=10)
simulator_tests/base_test.py, line 182
return subprocess.run(cmd, check=check, capture_output=capture_output, **kwargs)
simulator_tests/base_test.py, line 200
shutil.rmtree(self.test_dir)
simulator_tests/log_utils.py, line 90
result = subprocess.run(
simulator_tests/test_clink_agy_validation.py, line 109
version = subprocess.run(
simulator_tests/test_content_validation.py, line 175
os.remove(validation_file)
simulator_tests/test_per_tool_deduplication.py, line 229
os.remove(temp_path)
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
run-server.sh, line 341
echo " curl https://pyenv.run | bash" >&2
run-server.sh, line 1206
# - curl https://claude.ai/install.sh | bash -> ~/.local/bin/claude
docs/getting-started.md, line 77
curl -fsSL https://ollama.ai/install.sh | sh
Network
Serious
accepts a host from input, with no fixed list in this file.
NETWORK_HOST_FROM_INPUT
run-server.sh, line 538
# Try curl first
run-server.sh, line 539
if command -v curl &> /dev/null; then
run-server.sh, line 540
if curl -sSL "$get_pip_url" -o "$temp_pip" 2>/dev/null; then
Show more
run-server.sh, line 545
# Try wget if curl failed
run-server.sh, line 546
if [[ "$download_success" == false ]] && command -v wget &> /dev/null; then
run-server.sh, line 547
if wget -qO "$temp_pip" "$get_pip_url" 2>/dev/null; then
.codex/scripts/pretooluse-bash.sh, line 59
# --- Legacy capy HTTP routing (block curl/wget and inline HTTP patterns) ---
.codex/scripts/pretooluse-bash.sh, line 71
deny "curl is blocked. Use capy_fetch_and_index(url, source) or capy_execute() instead"
simulator_tests/test_secaudit_validation.py, line 166
response = requests.get(query)
Secrets
Concern
reads a credential or environment file.
SECRETS_ENV_READ SECRETS_PATH_DOTENV
run-server.ps1, line 9
- Configures environment files (.env)
run-server.ps1, line 488
Write-Info "API-backed tools (chat, consensus, etc.): configure a provider in .env or the launch environment."
run-server.ps1, line 840
# Ensure .env file exists
Show more
run-server.ps1, line 841
if (!(Test-Path ".env")) {
run-server.ps1, line 842
Write-Warning "No .env file found. Creating default .env file..."
run-server.ps1, line 871
$defaultEnv | Out-File -FilePath ".env" -Encoding UTF8
run-server.ps1, line 872
Write-Success "Default .env file created"
run-server.ps1, line 876
Write-Success ".env file exists"
simulator_tests/test_analyze_validation.py, line 185
secret_key: str = os.getenv("SECRET_KEY", "dev-key-not-secure")
simulator_tests/test_o3_model_selection.py, line 34
has_openai = bool(os.environ.get("OPENAI_API_KEY"))
simulator_tests/test_o3_model_selection.py, line 35
has_openrouter = bool(os.environ.get("OPENROUTER_API_KEY"))
simulator_tests/test_openrouter_fallback.py, line 33
has_openrouter = bool(os.environ.get("OPENROUTER_API_KEY"))
simulator_tests/test_openrouter_fallback.py, line 34
has_gemini = bool(os.environ.get("GEMINI_API_KEY"))
simulator_tests/test_openrouter_fallback.py, line 35
has_openai = bool(os.environ.get("OPENAI_API_KEY"))
simulator_tests/test_openrouter_models.py, line 34
has_openrouter = bool(os.environ.get("OPENROUTER_API_KEY"))
simulator_tests/test_xai_models.py, line 34
xai_key = os.environ.get("XAI_API_KEY", "")
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. the file cap was reached before every file was read.
OBFUSCATION_FILE_OVER_READ_CAP OBFUSCATION_FILE_CAP_REACHED
docs/feat/wip/server-reliability-and-capabilities/container-scan.json, line 1
{
tests/test_model_enumeration.py, 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 d25c2d029a5d. can delete files. install fetches a script from the network. The docs document an installer that pipes a download into a shell. accepts a host from input, with no fixed list in this file. reads a credential or environment file. a file was over the read cap and was not fully read. the file cap was reached before every file was read.
Date and source
Date checked:
github.com
Commit graded: d25c2d029a5d157935aa9bb836c18e9725969b8f
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.