mcpField
U
Unix pass

Unix pass

本地服务
github.com/Neanderthal安全22 天前更新

关于 Unix pass

Unix pass 是一个 MCP 服务,为 AI 工具提供访问现有 Unix `pass`/GPG 密码库的类型化接口。它适合需要密码与 TOTP 操作并希望按路径限制访问、通过显式设置控制写入的用户。

主要功能

  1. 01默认只读访问
  2. 02通过路径匹配限制条目范围
  3. 03读取密码和元数据
  4. 04生成 TOTP 验证码
  5. 05可选启用写入和 Git 操作

适用场景

  1. 01查询密码或条目字段
  2. 02根据条目生成 TOTP 验证码
  3. 03限制助手仅访问指定密码库路径

MCP 相关

它将密码库操作作为 MCP 工具提供,默认只读。写入、破坏性操作和网络操作需分别通过环境变量显式启用。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"neanderthal-unix-pass": {
"command": "uvx",
"args": [
"unix-pass-mcp"
],
"env": {
"PASS_MCP_ALLOWED_PATHS": "<PASS_MCP_ALLOWED_PATHS>",
"PASSWORD_STORE_DIR": "<PASSWORD_STORE_DIR>"
}
}
}
}
启动命令uvx unix-pass-mcp
需要配置的环境变量
PASS_MCP_ALLOWED_PATHSComma-separated entry globs. Scope the server to entries you intend to expose.
PASSWORD_STORE_DIR密钥Optional absolute password-store path; defaults to the user's ~/.password-store.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiunix-pass-mcp0.2.1

工具

24

收录的工具列表 · 更新于 1 天前

此工具无需参数。

详细介绍

██╗   ██╗███╗   ██╗██╗██╗  ██╗    ██████╗  █████╗ ███████╗███████╗    ███╗   ███╗ ██████╗██████╗
██║   ██║████╗  ██║██║╚██╗██╔╝    ██╔══██╗██╔══██╗██╔════╝██╔════╝    ████╗ ████║██╔════╝██╔══██╗
██║   ██║██╔██╗ ██║██║ ╚███╔╝     ██████╔╝███████║███████╗███████╗    ██╔████╔██║██║     ██████╔╝
██║   ██║██║╚██╗██║██║ ██╔██╗     ██╔═══╝ ██╔══██║╚════██║╚════██║    ██║╚██╔╝██║██║     ██╔═══╝
╚██████╔╝██║ ╚████║██║██╔╝ ██╗    ██║     ██║  ██║███████║███████║    ██║ ╚═╝ ██║╚██████╗██║
 ╚═════╝ ╚═╝  ╚═══╝╚═╝╚═╝  ╚═╝    ╚═╝     ╚═╝  ╚═╝╚══════╝╚══════╝    ╚═╝     ╚═╝ ╚═════╝╚═╝

将现有的 Unix pass/GPG 存储连接到 AI 工具。

默认只读。写入、密钥管理和网络操作均需通过明确的环境变量选择启用。 所有子进程调用都经过单一入口。严格验证输入。不使用 Shell,不访问剪贴板,不在日志中记录机密。

Python 3.11+ License: MIT MCP 2.3 Tests


状态 — M5 已完成。 读取 · 安全写入 · 密钥管理 · TOTP/OTP · git · 加固功能均已发布。 24 个工具,配备单元测试、真实 GPG 集成测试和 stdio 协议回归测试套件。 请参阅安装示例、演示和 发布/发布流程说明。

演示

使用合成存储进行真实 MCP 调用

83 秒 MP4 · 录制方式

正在试用 Beta 版?反馈安装体验。 发布状态分别跟踪软件包和目录的发布进度。

目录


为何创建此项目

pass 是对 gpg(1) 和文件系统的轻量封装。任何可以调用 Shell 的程序都能使用它——但直接将它暴露给 LLM,无异于自找 rm -rf 的麻烦。本服务提供:

  • 在安全的 pass 子集之上构建的类型化 MCP 接口。
  • 默认只读;写入和破坏性操作均需通过明确的环境变量选择启用。
  • 严格验证输入——不使用 Shell、不允许路径逃逸、不允许通过 stdin 偷带机密。
  • 经过净化的错误输出、仅追加的审计日志,以及 gpg-agent 预检。

完整设计和安全模型请参阅 .claude/rules/architecture.md。


快速入门

需要 Python 3.11+、uv、pass、GnuPG 和已初始化的存储。 安装已发布到 PyPI 的版本:

claude mcp add unix-pass -e 'PASS_MCP_ALLOWED_PATHS=web/*' -- \
  uvx --from unix-pass-mcp==0.2.1 unix-pass-mcp

可直接复制粘贴的配置:Codex、 Claude Code、 Claude Desktop。 源码检出开发和其他客户端设置详情,请参阅安装说明。

这样即可使用只读接口。要启用修改操作:

PASS_MCP_ALLOW_WRITES=1 \
PASS_MCP_ALLOWED_PATHS=web/* \
uv run unix-pass-mcp

要求

必需
组件用途备注
Python ≥ 3.11运行时已在 CI 中测试 3.11 / 3.12 / 3.13
PATH 中的 pass被封装的二进制程序pass --version 必须正常运行
PATH 中的 gpg(GnuPG ≥ 2.2)解密仅由 unlock_agent 直接使用
gpg-agent缓存口令服务启动时会探测 gpg-connect-agent /bye;若无法连接到 Agent,则拒绝解密。GnuPG 首次使用时会自动启动。
已配置的 GPG 密钥解密 / pass init 所需信任级别必须设置为“ultimate”——参见 Arch wiki
已初始化的密码存储管理对象如果尚无密码存储,请运行 pass init <gpg-id>
Pinentry — 选择一种方式

服务本身无法弹出交互式密码短语提示框——pass/gpg 会一直挂起。你需要使用以下一种方式:

  1. 在 ~/.gnupg/gpg-agent.conf 中配置一个 GUI pinentry——pinentry-gnome3、pinentry-qt、pinentry-qt5 或 pinentry-gtk-2。每个缓存窗口内首次解密时,桌面会弹出对话框。推荐。
  2. 安装 zenity 或 kdialog——每个缓存窗口调用一次 unlock_agent MCP 工具,为 gpg-agent 预热缓存。如果你无法修改 gpg-agent.conf,请使用此方式。
  3. 使用已预热的 Agent——在与 MCP 通信前,先在真实终端中运行 pass show <name>。缓存会在 default-cache-ttl 设定的时间后过期(默认 600s)。
OS 安装提示
# Arch / Manjaro
sudo pacman -S pass gnupg pinentry zenity         # zenity optional, for unlock_agent

# Debian / Ubuntu
sudo apt install pass gnupg pinentry-gnome3 zenity

# Fedora
sudo dnf install pass gnupg2 pinentry-gnome3 zenity

# macOS (Homebrew)
brew install pass gnupg pinentry-mac
可选组件
组件提供的功能
pass-otp让 otp 与其他工具兼容(服务原生实现了 RFC 6238,无运行时依赖)
git如果你的存储库是 git 仓库,则在写入时自动提交,并提供 git_status / git_log / git_pull / git_push
开发
组件用途
uv推荐的安装器 / 运行器
支持生成密钥的 gpg集成测试会在临时 GNUPGHOME 中生成一次性密钥

安装

uv sync --locked --extra dev # for development
uv pip install .             # for use

接入 MCP 主机

Claude Desktop

添加到 ~/.config/Claude/claude_desktop_config.json(或对应平台的配置文件):

{
  "mcpServers": {
    "pass": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/unix-pass-mcp", "unix-pass-mcp"],
      "env": {
        "PASSWORD_STORE_DIR": "/home/you/.password-store"
      }
    }
  }
}
Claude Code
# Read-only
claude mcp add pass -- uv run --directory /absolute/path/to/unix-pass-mcp unix-pass-mcp

# With writes enabled and path scope (recommended pairing)
claude mcp add pass -s user \
  -e PASS_MCP_ALLOW_WRITES=1 \
  -e PASS_MCP_ALLOWED_PATHS='web/*' \
  -- uv run --directory /absolute/path/to/unix-pass-mcp unix-pass-mcp

每个 -e KEY=VALUE 标志都会为启动的服务设置一个环境变量。若要更改现有服务的环境变量,请先运行 claude mcp remove pass -s user,然后重新添加——CLI 不支持就地编辑。使用 claude mcp get pass 验证。

驱动自主 Agent

对于将 unix-pass-mcp 与可控制浏览器的 MCP 结合使用的账号创建 / 资料填写工作流,请将 .claude/rules/agent-workflow.md 加载到 Agent 的系统提示词中。该文件定义了规范的命名约定(web/<domain>/<handle>)、正文格式,以及注册 / 登录 / 轮换流程。


工具

共 24 个工具,按能力门控分组。

只读——始终可用
工具描述
store_info检查存储库:路径、各子目录的接收者、git/Agent/pinentry/签名状态及警告。不解密。
list列出 pass 名称(可选限定子文件夹)。不解密。
find在叶节点名称中搜索子字符串。不解密。
show解密并返回条目中的一行(默认 = 第 1 行 = 密码)。标记为敏感。
show_field解密并返回一个指定的元数据字段(URL、Username、otpauth 等)。不区分大小写。
show_metadata解密后仅返回条目结构(字段名称、是否含密码及行数)。不会返回密码值。
unlock_agent弹出桌面密码对话框(zenity/kdialog),并通过 loopback pinentry 为 gpg-agent 预热缓存。对于多接收者存储库,可选用 target——如果不带参数调用返回 wrong_passphrase_or_decrypt_failed,请传入明确的 pass 名称;在一些将条目加密给已轮换子密钥的旧版存储库中,可能会出现此情况。大模型永远不会看到密码短语。
grep在获准访问的条目解密后正文中搜索。速度慢且成本高(会解密获准访问的条目)——需要 confirm_decrypt_all=true。标记为敏感。遵循 PASS_MCP_ALLOWED_PATHS。
otp根据条目的 otpauth:// 行计算当前 TOTP 验证码。返回验证码和 seconds_remaining。标记为敏感。原生实现 RFC 6238——无 pass-otp 运行时依赖。
otp_uri返回原始 otpauth:// URI(含密钥)。仅在其他位置重新注册同一密钥时使用。
写入 — 需设置 PASS_MCP_ALLOW_WRITES=1 才能使用
工具描述
insert创建或覆盖单行条目。密码通过 stdin 传入(绝不会通过 argv 传入)。未设置 force=true 时拒绝覆盖。
insert_multiline创建或覆盖完整正文条目(第 1 行为密码,其余为 Key: value 元数据)。
set_field更新一个 Key: value 字段;保留密码和其他行。simulate=true 会返回将要写入的正文,但不实际写入。
unset_field移除所有与字段键匹配的行(不区分大小写)。如果不存在则不执行任何操作。设置 simulate=true 可进行试运行。
generate生成新密码(长度为 1–1024,可选 no_symbols)。in_place=true 会保留元数据;force=true 会覆盖所有内容。返回生成的值(敏感信息)。
mv重命名或移动条目/子文件夹。如果目标子文件夹的接收者不同,则使用其接收者重新加密。
cp复制条目/子文件夹,重新加密语义相同。
otp_set在现有条目中追加或替换 otpauth:// URI。写入前会验证 URI。
Git — git_status 和 git_log 始终可用;git_pull 和 git_push 需设置 PASS_MCP_ALLOW_NETWORK=1
工具描述
git_status结构化状态:{clean, branch, upstream, ahead, behind, dirty_files}。如果存储目录不是 git 仓库,则拒绝执行。
git_log最近的提交,格式为 [{hash, subject}, …]。limit 默认为 20(最大值为 200)。
git_pullgit pull --ff-only — 若存在分歧则拒绝执行,不创建合并提交,也不变基。
git_pushgit push — 绝不使用 --force。
破坏性操作 — 需设置 PASS_MCP_ALLOW_DESTRUCTIVE=1 才能使用
工具描述
init使用新的 GPG 接收者初始化存储目录(或子文件夹)。重新加密范围内的每个条目。如果用户没有任何新接收者的密钥,则拒绝执行,除非设置了 force=true。空的 gpg_ids 列表会移除子文件夹的 .gpg-id。
reencrypt使用当前接收者重新运行 init。适用于子密钥轮换后。接收者未发生变化时不执行任何操作。

完整的机器可读接口——包括每个参数和每个错误代码——位于 .claude/rules/api.md。


配置

服务器专用环境变量:

变量默认值作用
PASS_MCP_ALLOW_WRITES未设置使用任何会修改数据的工具时都必须设置
PASS_MCP_ALLOW_DESTRUCTIVE未设置使用 init / reencrypt 时必须设置
PASS_MCP_ALLOW_NETWORK未设置使用 git_pull / git_push 时必须设置
PASS_MCP_ALLOW_UNSAFE未设置绕过严格的启动检查(存储目录对所有用户可读、弱 umask)。不要设置。
PASS_MCP_ALLOWED_PATHS未设置(= 所有路径)以逗号分隔的 fnmatch glob,用于限定服务器可操作的条目
PASS_MCP_GREP_TIMEOUT_SECONDS120grep 的单次调用超时时间(会解密允许访问的条目)
PASS_MCP_REQUIRE_AGENT1如果无法连接 gpg-agent,则拒绝解密
PASS_MCP_AUDIT_LOG~/.local/state/unix-pass-mcp/audit.log仅追加的操作 JSONL 日志;设为空字符串可禁用
PASS_MCP_TIMEOUT_SECONDS15单次调用的子进程超时时间

标准 pass 环境变量会传递过去(PASSWORD_STORE_DIR、PASSWORD_STORE_KEY、PASSWORD_STORE_UMASK 等)。完整列表请参阅 .claude/rules/architecture.md §5。

不会传递的变量:

  • PASSWORD_STORE_GPG_OPTS — 恶意环境可借此注入 gpg 标志,例如 --recipient(悄无声息地将数据重新加密给攻击者)或 --output(外泄解密内容)。
  • PASSWORD_STORE_X_SELECTION、PASSWORD_STORE_CLIP_TIME — 剪贴板工具已移除(通过 MCP 使用时没有意义)。

安全态势

不使用 shell。每次 pass 调用都通过唯一入口(pass_cli.run),使用参数列表并禁用 shell 执行。进程启动操作统一由 pass_cli.execute 处理。
严格验证输入。密码条目名称必须匹配 ^[A-Za-z0-9._@-][A-Za-z0-9._@/-]*$,长度不超过 256 个字符,不得包含 ..、不得以 - 开头,也不得包含控制字符。gpg-id 必须匹配正向允许列表。
路径允许列表。PASS_MCP_ALLOWED_PATHS 可将服务的访问范围限定为 "work/*,personal/notes/*" 等路径,以限制向 MCP 主机公开的条目。grep 和 unlock_agent 也遵循此限制。
标记敏感输出。show、show_field、generate、otp、otp_uri、grep 和模拟字段操作均带有 meta.sensitive = true,以便 MCP 主机拒绝记录或缓存相关内容。
清理标准错误输出。抛出错误前,会移除 -----BEGIN/-----END 标记之间的所有内容;输出截断至 2 KB。
审计日志仅记录名称。绝不记录值、字段内容或 grep 模式。
隔离标准输入。除非调用方正在主动通过管道传输内容,否则每个子进程都会以 stdin=DEVNULL 运行。这可保护 MCP 的 stdio JSON-RPC 帧,避免子进程意外读取数据。
严格启动检查。如果 PASSWORD_STORE_UMASK 的安全性低于 077,或者密码库目录可被所有用户读取,则拒绝启动。可通过 PASS_MCP_ALLOW_UNSAFE=1 绕过(请勿这么做)。

服务指示模型将返回的机密视为机密信息,绝不在回复、摘要、日志或无关的工具调用中复述。这只是对模型的指导,并非技术层面的日志隔离措施:MCP 客户端仍可能将原始工具结果保存在对话记录中。请相应地检查并配置主机的对话记录和日志策略。

将机密传递给本地应用程序

此服务尚未提供从 pass 到本地应用程序的隐藏式服务端传递机制。show 工具会将请求的值返回给 MCP 主机和模型。请勿让 Agent 通过 shell 运行 pass show 作为变通方案:这样会绕过此服务的路径检查和审计策略,并可能导致输出暴露在工具历史记录中。通用传递机制需要借助本地客户端/代理路径,确保机密不会进入助手对话记录,或通过明确由用户介入的方式传递。仅靠 MCP 工具说明无法提供此类通道。


运行行为

限定范围的搜索

grep 会先筛选允许访问的条目名称,再逐个解密,并使用基本正则表达式搜索条目正文。类似标头的内容不会更改条目名称。模式会作为操作数处理,包括以 - 开头的模式;无效模式会在解密前导致操作失败。PASS_MCP_GREP_TIMEOUT_SECONDS 是适用于整个搜索过程的正数有限总时限。redacted_entries 始终为零,因为被排除的条目不会参与搜索。

文件系统隔离

条目访问会拒绝符号链接文件和目录组件,包括密码库内部的链接。发现条目和自动解锁的目标选择过程会跳过链接。显式指定的解锁目标会在探测 Agent 前进行验证。请确保本地密码库归可信用户所有:这些 CLI 检查无法隔离同一用户运行的其他进程对文件系统进行的并发更改。

发现与 git 范围

list 和 find 会排除不允许访问的条目。启用路径范围限制时,接收者发现功能只会报告可见条目的祖先目录。远程 URL 会省略用户信息、查询参数和片段。Git 工具会操作整个代码库,因此要求访问不受限(未设置路径允许列表,或明确授予 *);部分路径授权不足以授权访问 git 历史记录或执行代码库范围的网络操作。

结构化元数据和敏感结果

show_metadata 会返回 field_names、password_present 和 raw_lines。它不会 返回字段值、密码、自由文本或 OTP URI。此行为取代了原先的 fields 映射。若要显式读取敏感字段,请使用 show_field。 这两个字段编辑工具都会声明输出敏感,因为模拟结果包含完整的解密前后正文。自定义敏感元数据只是主机提示,并非协议对日志记录或缓存的保证。搜索查询不会被审计。

PASS_MCP_TIMEOUT_SECONDS 用于设置默认子进程超时时间。它必须是正的有限数值;无效值会在命令执行前导致失败。显式操作预算(搜索、密钥管理和网络操作)会覆盖此值。

运行时和取消

MCP 处理程序在工作线程中运行,因此缓慢的 GPG 操作不会阻塞协议处理。变更类工具调用会串行执行,以防止读/修改/写入操作重叠。取消会向工作线程发送信号并终止其子进程组;每条命令的超时时间仍会限制执行时长。取消无法回滚 pass 已完成的更改;重试写入前请检查条目。生产环境中的子进程启动(包括解锁对话框)都集中在 pass_cli.execute 中。本地工具声明 openWorldHint: false;网络 git 工具声明 openWorldHint: true。

MCP SDK 兼容性

服务器使用官方 SDK v2 的 MCPServer API,并要求 mcp>=2.3,<3。 其 stdio 传输同时支持旧版初始化和 2026 年 7 月推出的按请求元数据/发现机制。 测试会以两种模式启动真实的 stdio 客户端。锁文件记录了经过测试的依赖集;使用 uv sync --locked --extra dev 可复现该环境。


开发

uv run ruff check
uv run ruff format --check
uv run pytest -q tests/unit                                 # fast tests
PASS_MCP_INTEGRATION=1 uv run pytest -q tests/integration   # real-GPG tests

集成测试套件会在临时 GNUPGHOME 中创建一个仅供测试使用的 RSA 密钥(有效期 1 天,无密码),并运行真实的 pass 进行测试。CI 会在 Python 3.11 / 3.12 / 3.13 上运行这两个层级的测试。


免责声明

unix-pass-mcp 是密码库与非确定性大模型之间的桥梁;在大多数实际部署中,它还连接着密码库与所有共享同一模型会话的其他 MCP 服务(浏览器自动化、Shell 执行、Web 请求)。即使默认禁用了所有权限门控,安装此服务的目的就是让大模型访问你的机密。以下情况并非错误:

  • 大模型可以被提示(由你、浏览器 MCP 加载的恶意网页,或遭到投毒的工具结果提示),解密 PASS_MCP_ALLOWED_PATHS 范围内的任意条目,并将其转发给同一会话中的其他工具。
  • 设置 PASS_MCP_ALLOW_WRITES=1 后,大模型可以覆盖、重命名或生成条目,取代范围内的现有条目。
  • 设置 PASS_MCP_ALLOW_DESTRUCTIVE=1 后,大模型可以将你的密码库重新加密给另一组接收者,或删除某个子文件夹的 .gpg-id。
  • 设置 PASS_MCP_ALLOW_NETWORK=1 后,大模型可以向配置的 git 远程仓库推送提交,包括凭据变更。

权限门控、路径允许列表、审计日志、敏感输出标记和验证加固措施,可以缩小错误和提示注入的影响范围。但它们并不能让无人监督的 Agent 安全地访问生产凭据库。请将上述安全态势视为针对恶意且快速演变的威胁模型所做的尽力而为的工程实践,而非正式保证。

你须全权负责:

  • 启用哪些权限门控,以及在哪些密码库上启用。
  • 运行此服务的 MCP 主机的信任边界——它会记录、缓存、发送到遥测系统什么内容,或允许其他服务查看什么内容。
  • 在授予破坏性操作或网络访问权限前,备份 ~/.password-store(以及 ~/.gnupg)。
  • 定期检查 ~/.local/state/unix-pass-mcp/audit.log。
  • 从 Agent 造成的任何错误中恢复——没有撤销操作。

本软件按“原样”提供,不附带任何明示或默示的保证,包括但不限于适销性、特定用途适用性和不侵权保证。作者和贡献者不对任何索赔、损害或其他责任承担责任,包括但不限于数据丢失、凭据泄露、密码库锁定、机密意外披露或服务中断,无论这些后果是由错误、提示注入、配置错误,还是任何其他对本软件的使用或滥用造成。完整的 MIT 条款请参阅 LICENSE。

本项目与 Anthropic、pass(1) 的维护者(Jason A. Donenfeld 和贡献者)、GnuPG 项目或任何 MCP 主机供应商均无关联,也未获得其认可或赞助。所有商标均归其各自所有者所有。


许可证

MIT——请参阅 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。