MCP, MCP server
penpal
给你所有 AI 共用的本地记忆。 Penpal 在你的 Mac 上记下你看过、写过、问过的东西,通过 MCP 交给 Claude Code、Codex、Cursor 查询,每条结果都能打开出处,每个 AI 能看到什么由你授权。
Compatibility: Not stated.
Grade B
Minor issues only, no Medium or High. Worth a quick look at the findings below before installing.
Not a guarantee. A hygiene check of the source at the commit shown, not a security audit.
PERMISSION_DELETE_FILES SECRETS_PATH_DOTENV INSTALL_DOCUMENTED_INSTALLER NETWORK_NAMED_HOST SECRETS_ENV_READ OBFUSCATION_FILE_CAP_REACHED
Why this grade
- PERMISSION_DELETE_FILES Low
Contains a call that can delete files.
evals/fixtures.py, line 165
subprocess.run(["git", "init", "-q", "-b", "main"], cwd=repo, check=True, env=env_base, capture_output=True) - SECRETS_PATH_DOTENV Low
Mentions a .env file.
penpal/utils/env.py, line 41
target = path or (get_data_dir() / ".env") - INSTALL_DOCUMENTED_INSTALLER Note
Documentation shows an installer that pipes a download into a shell.
README.en.md, line 46
curl -fsSL https://raw.githubusercontent.com/Longfellow1/penpal/main/install.sh | bash - NETWORK_NAMED_HOST Note
Calls a fixed host that the description names.
install.sh, line 195
echo ' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"' - SECRETS_ENV_READ Note
Reads an environment variable whose name contains KEY, SECRET, TOKEN, PASSWORD or CREDENTIAL.
penpal/utils/env.py, line 32
"""Load KEY=VALUE lines from ~/.penpal/.env into os.environ. - OBFUSCATION_FILE_CAP_REACHED Note
The 400 file cap was reached before every file was read.
tests/test_sources_approved_sqlite.py, line 1
from __future__ import annotations
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
evals/fixtures.py, line 165
subprocess.run(["git", "init", "-q", "-b", "main"], cwd=repo, check=True, env=env_base, capture_output=True)
evals/fixtures.py, line 168
subprocess.run(["git", "config", key, value], cwd=repo, check=True, env=env_base, capture_output=True)
evals/fixtures.py, line 173
subprocess.run(["git", "add", "."], cwd=repo, check=True, env=env, capture_output=True)
Show more
evals/fixtures.py, line 174
subprocess.run(
evals/realdata/judge.py, line 74
proc = subprocess.run(cmd, cwd=d, capture_output=True, text=True, timeout=timeout,
evals/realdata/paths.py, line 26
r = subprocess.run(["git", "-C", str(probe), "rev-parse", "--is-inside-work-tree"],
evals/realdata/runner.py, line 248
proc = subprocess.run(cmd, cwd=workdir, capture_output=True, text=True, timeout=timeout,
penpal/cli.py, line 151
result = subprocess.run(["launchctl", "list"], check=False, capture_output=True, text=True)
penpal/cli.py, line 571
shutil.rmtree(target)
Install and update
Note
README documents an installer that pipes a download into a shell. The docs document an installer that pipes a download into a shell.
INSTALL_DOCUMENTED_INSTALLER
README.en.md, line 46
curl -fsSL https://raw.githubusercontent.com/Longfellow1/penpal/main/install.sh | bash
README.md, line 46
curl -fsSL https://raw.githubusercontent.com/Longfellow1/penpal/main/install.sh | bash
docs/说明-homebrew-cli-integration-requirements.md, line 40
curl -fsSL https://raw.githubusercontent.com/Longfellow1/penpal/main/install.sh | bash
Show more
docs/说明-homebrew-install.md, line 10
curl -fsSL https://raw.githubusercontent.com/Longfellow1/penpal/main/install.sh | bash
Network
Note
can reach raw.githubusercontent.com.
NETWORK_NAMED_HOST
install.sh, line 195
echo ' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
Secrets
Concern
reads a credential or environment file.
SECRETS_ENV_READ SECRETS_PATH_DOTENV
penpal/utils/env.py, line 41
target = path or (get_data_dir() / ".env")
scripts/compat-wrapper.sh, line 7
grep -Eq '^[[:space:]]*(source|\.)[[:space:]].*\.keypulse/secrets\.env' "$path" && \
penpal/utils/env.py, line 32
"""Load KEY=VALUE lines from ~/.penpal/.env into os.environ.
Show more
docs/reviews/penpal-review-2026-04-30/README.md, line 176
- **影响**:daemon 环境 Keychain 经常不可用(参见 b192a56 的 .env 补丁),用户看到"LLM 没响应"但不知道是哪种失败
docs/reviews/penpal-review-2026-04-30/README.md, line 301
- API key 报错有 `.env` fallback 兜底(commit b192a56)
docs/reviews/penpal-review-2026-04-30/README.md, line 521
- `KeychainUnavailable` → WARN,提示用户解锁 Keychain 或用 .env
docs/设计-openspace-inspired-penpal-evolution-plan.md, line 446
已在 2026-06-05 使用 `anyint/deepseek-v4-pro` 做外部评审。评审先通过 `decision-advisor` MCP 发起,MCP 中 `.env` 的 AnyInt key 返回 401;随后改用 keychain 中的 `codex-anyint-api-key` 直接调用 AnyInt,同模型评审成功。
Agent instructions
Pass
No instruction to ignore earlier instructions or to hide a step.
Obfuscation
Note
the file cap was reached before every file was read.
OBFUSCATION_FILE_CAP_REACHED
tests/test_sources_approved_sqlite.py, line 1
from __future__ import annotations
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 bf8c02580bee. can delete files. README documents an installer that pipes a download into a shell. The docs document an installer that pipes a download into a shell. can reach raw.githubusercontent.com. reads a credential or environment file. the file cap was reached before every file was read.
Date and source
Date checked:
github.com
Commit graded: bf8c02580beee55259acf675bec2c79a75a1dfe9
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.