passkey-mcp
A cross-platform secrets manager that stores named credential sets in the system keychain and injects them as environment variables, enabling secure secret management for AI coding assistants and CLI tools.
README
Passkey
A cross-platform secrets manager for AI coding assistants and CLI tools — stores named credential sets in your system keychain and injects them as environment variables at runtime.
No plaintext secrets in config files. No cloud sync. Touch ID / system auth protected.
Features
- Store multiple secrets per entry in the system keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service)
- Inject secrets as environment variables for subprocesses
- Tool-agnostic — works with Claude, Gemini, VS Code, Cursor, OpenCode, Windsurf, Cline, Zed, and more
- Interactive fuzzy-search entry picker (arrow keys + type-to-filter)
- Tab completion for bash, zsh, and fish
- Import from Chrome password exports, existing MCP configs, or passkey backups
- Encrypted bundle export/import for safe machine-to-machine transfer
- Full audit logging of all operations
- Touch ID / system auth protection (honors your sudo PAM config)
- Cross-platform: macOS, Linux, Windows
Installation
# Recommended: install globally with pipx
pipx install passkey-mcp
# Or with pip
pip install passkey-mcp
# Development mode (from source)
pip install -e .
Requirements
- Python 3.10+
- System keychain access (macOS Keychain, Windows Credential Manager, or a running Linux keyring daemon)
Quick Start
# First run — guided onboarding
passkey
# ┌─────────────────────────────────────────────┐
# │ Welcome to passkey │
# │ Secrets in your keychain. Not in config. │
# └─────────────────────────────────────────────┘
# Create your first entry now? [Y/n]
# Create an entry
passkey new
# Entry name: github
# Field name: GITHUB_TOKEN
# Value: [hidden input]
# List all entries
passkey list
# Run a command with secrets injected
passkey run github -- python app.py
Shell Completion
Set up tab completion for your shell:
# Zsh (macOS default)
eval "$(passkey completion --zsh)"
# Bash
eval "$(passkey completion --bash)"
# Fish
passkey completion --fish > ~/.config/fish/completions/passkey.fish
After setup, tab completion works everywhere:
passkey <TAB> # Show entries + subcommands
passkey hugg<TAB> # Fuzzy-match: huggingface_key
passkey get <TAB> # Complete entry names
passkey run <TAB> # Pick entries to load
Interactive Mode
When you omit an entry name (or type a partial match), passkey shows an interactive picker with fuzzy search:
$ passkey get
? Select entry to browse: (Use arrow keys, type to filter)
❯ github
openai
slack
myapi_read
myapi_write
# Type to filter:
$ passkey get my
# Automatically shows: myapi_read, myapi_write
# Single match auto-selects:
$ passkey get github
Copied 'GITHUB_TOKEN' to clipboard (auto-clears in 30s)
# Shortcut: passkey <entry> opens the picker directly
$ passkey github
Fuzzy Matching
- Prefix:
mymatchesmyapi_read,myapi_write - Contains:
apimatchesmyapi_read,myapi_write - Sequence:
ghmatchesgithub - Case-insensitive:
GITHUBmatchesgithub
CLI Reference
Entry Management
| Command | Description |
|---|---|
passkey new |
Create a new entry interactively |
passkey list |
List all entry names |
passkey list --names-only |
Entry names only (one per line, for scripting) |
passkey edit [entry] |
Modify an existing entry |
passkey delete [entry] |
Delete an entry (exact match required) |
passkey info [entry] |
Show entry metadata and field names |
passkey clone SOURCE [DEST] |
Clone an entry under a new name |
passkey set-field ENTRY FIELD [VALUE] |
Upsert a single field |
Retrieving Secrets
| Command | Description |
|---|---|
passkey get [entry] |
Interactive field picker — select a field to copy |
passkey get [entry] --all |
Copy all fields to clipboard |
passkey <entry> |
Shortcut: same as passkey get <entry> |
Running Commands
# Run with secrets from one entry
passkey run github -- python app.py
# Run with secrets from multiple entries (later entries override)
passkey run aws github -- python deploy.py
# Secrets injected as env vars
passkey run myapi -- curl -H "Authorization: Bearer $API_TOKEN" https://api.example.com/v1/data
Tool Integration
# Scan configs and migrate plaintext secrets to keychain
passkey init # Auto-detect all tools
passkey init --tool claude # Specific tool
passkey init --tool vscode
# Show security status across all tools
passkey status
# Run diagnostics
passkey doctor
# List MCP servers across tools
passkey servers
Supported tools: claude, claude_desktop, gemini, vscode, cursor, opencode, windsurf, cline, zed
Export and Backup
# Export all entries to file (owner-only permissions set automatically)
passkey export backup.json
# Export specific entries
passkey export backup.json --entries github openai
# Export metadata only (no secret values)
passkey export backup.json --no-secrets
# Encrypted export (AES-256-GCM + scrypt)
passkey export backup.passkey.enc --encrypt
Import
# Import from passkey backup
passkey import backup.json
# Preview without importing
passkey import backup.json --dry-run
# Handle duplicates: skip (default), overwrite, merge
passkey import backup.json --mode merge
# Import from encrypted bundle
passkey import backup.passkey.enc --decrypt
# Import from Chrome password export (CSV)
passkey import passwords.csv --filter github.com
# Import from an existing MCP config file
passkey import claude_desktop_config.json
Audit Log
passkey audit # View recent operations
passkey audit --limit 50 # Show more entries
passkey audit --clear # Clear the log
Verify Entry Health
# Exit non-zero if any required fields are missing
passkey check github GITHUB_TOKEN GITHUB_USERNAME
Authentication
Passkey requires OS-level authentication before any secret access. This uses your system's PAM configuration:
- macOS with Touch ID: Touch ID prompt (if configured in
/etc/pam.d/sudo) - macOS without Touch ID: Admin password dialog
- Linux: PolicyKit dialog (GNOME/KDE) or password prompt
- Windows: UAC elevation dialog
Credentials are cached for 5 minutes (same as sudo).
MCP Config Example
Before (insecure — secret in plaintext):
{
"mcpServers": {
"github": {
"command": "python",
"args": ["-m", "github.server"],
"env": {
"GITHUB_TOKEN": "ghp_PLAINTEXT_SECRET_HERE"
}
}
}
}
After (secure — secret loaded from keychain at runtime):
{
"mcpServers": {
"github": {
"command": "passkey",
"args": ["run", "github", "--", "python", "-m", "github.server"]
}
}
}
MCP Server Mode
Passkey can run as an MCP server itself, letting AI assistants invoke passkey tools via natural language:
{
"mcpServers": {
"passkey": {
"command": "passkey-mcp-server"
}
}
}
Available tools: passkey_list, passkey_fields, passkey_status, passkey_doctor, passkey_wrap_server.
AI assistants can discover entry names but never see secret values — secrets only flow out via passkey run.
Data Storage
| Platform | Data directory |
|---|---|
| macOS | ~/Library/Application Support/passkey/ |
| Linux | ~/.config/passkey/ (respects $XDG_CONFIG_HOME) |
| Windows | %APPDATA%\passkey\ |
Secrets themselves are stored in the system keychain, not on disk. The data directory holds metadata (lock file, audit log).
Security
- Encrypted at rest: System keychain handles encryption (AES-256-GCM on macOS, DPAPI on Windows)
- No secrets logged: Only entry names and operation types appear in the audit log
- Hidden input:
getpassused for all secret entry - Clipboard auto-clear: Copied secrets cleared after 30 seconds
- Secure export: Files created with
chmod 600(owner-only) - Encrypted bundles: AES-256-GCM + scrypt (N=2^20) for portable transfer
- LLM-safe: AI assistants can list entries but never read values
See docs/SECURITY.md for full details.
Troubleshooting
"Failed to access Keychain" (macOS)
Grant Terminal / Python keychain access in System Settings → Privacy & Security.
Touch ID not working
Ensure pam_tid.so is configured in /etc/pam.d/sudo:
sudo sed -i '' '2i\
auth sufficient pam_tid.so
' /etc/pam.d/sudo
Linux headless / no keyring daemon
Set a backend explicitly:
export PYTHON_KEYRING_BACKEND=keyring.backends.SecretService.Keyring
# or for headless environments:
export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring
Entry not found
passkey list # check exact names (case-sensitive)
Import shows "skipped (exists)"
passkey import backup.json --mode merge
Development
pip install -e ".[dev]"
pytest tests/ -v
ruff check passkey/
License
MIT — see LICENSE
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。