safehold
Local MCP server for securely storing and sharing identity documents (passports, visas, licenses) with AI agents, requiring per-field user consent for each request.
README
Safehold
Your identity documents, on your machine, shared only when you say so.
What it is
Safehold is a local MCP server that stores passports, visas, driving licences, and other identity documents. When an AI agent needs your passport number to book a flight, it asks Safehold. You see what's being requested and why, then approve or deny. Nothing leaves your device.
Why it exists
Your identity data is scattered across dozens of services you don't control: banks, airlines, government portals, SaaS products. Each one holds a copy and decides for itself how to store it, whether to sell it, and how long it'll stick around. AI agents make this worse. Anything an agent can access, every API it touches can reach too.
Safehold is the alternative. The agent gets a field value. You get a consent prompt instead of a privacy policy. Your files stay where they are.
Open source, so none of this requires trust.
What it isn't
A few things that get confused with safehold but solve a different problem.
1Password, Bitwarden, op CLI
You can stuff a passport into 1Password. The op CLI can read specific fields. There's even an official 1Password MCP server now. So yes, parts of this overlap.
What's different is the trust model. Once your 1Password vault is unlocked, anything with that session can read anything in it. No per-field consent, no "why are you asking for this?" prompt. The vault is built for humans typing passwords, not for agents pulling structured fields with a stated reason.
Safehold gates each field individually, every time, with a purpose attached.
Browser autofill, Apple Passwords, iCloud Keychain
Works fine if your agent is a browser filling a form. Doesn't help when it isn't. Agents working over APIs, CLI tools, or other MCP servers never see the autofill layer, so you end up copy-pasting from a passwords app into a chat anyway. Safehold gives a non-browser agent a way to request a passport number without that detour.
Apple Wallet, Google Wallet, government digital ID apps
Locked to the platform. Apple Wallet won't hand your boarding pass to a third-party agent. mDL pilots and the EU eIDAS wallet are issuer-controlled and narrow in scope. None of them speak MCP, and none will let an agent on your laptop request a field from your driving licence.
Pasting it into the chat
People do this. They drop their passport number into a system prompt, or type it into a message and trust the agent to handle it. The number then lives in chat history, gets shipped to the model provider, and sticks around in their logs. You also have no record of which agent used it for what.
Safehold keeps the document on disk, encrypted, and only releases the one field the agent asked for. Nothing extra ends up in the conversation.
A plain JSON file plus the filesystem MCP
Tempting if you're a developer. ~/identity.json plus the filesystem MCP is three lines of config and done. It also gives every other agent on the box the same access, with no encryption at rest, no logging, and no consent step. The first time that file shows up in a backup or a screen share, you have a problem.
Persona, Stripe Identity, Onfido, Plaid
KYC vendors. You send them your documents, they store them, and partner services query them on your behalf. The model assumes you don't hold the keys. Safehold takes the other direction: documents stay on your machine and you approve every release.
HashiCorp Vault, AWS Secrets Manager, Doppler, Infisical
Built for service secrets, not personal identity. No human-facing consent flow, no schema for documents, and operationally heavy for someone who just wants their passport readable by an agent on their laptop.
How it works
Safehold runs as a stdio MCP server. Documents go into ~/.safehold/vault/ as individual encrypted files. Every retrieval is logged to ~/.safehold/access-log.enc.
Encryption is XChaCha20-Poly1305 via @noble/ciphers, audited by Cure53, no external dependencies. On first run a 32-byte key is written to ~/.safehold/master.key (mode 0600).
Other MCP clients can request specific fields from your documents. You control what gets shared, every time.
Tools (v1)
| Tool | Description |
|---|---|
add_document |
Add a document to the vault |
list_documents |
List stored documents (metadata only) |
update_document |
Update fields on an existing document |
delete_document |
Permanently delete a document |
get_passport |
Retrieve specific fields from a passport |
get_national_id |
Retrieve specific fields from a national ID |
get_driving_license |
Retrieve specific fields from a driving licence |
get_visa |
Retrieve specific fields from a visa |
get_photo |
Retrieve a stored photo (passport style, selfie, or signature) |
get_document |
Retrieve fields from any document type |
get_access_log |
View what was accessed, by which client, and when |
Every retrieval tool accepts a purpose parameter. That purpose is shown to you at consent time so you always know why a field is being requested.
Prompts (v1)
Safehold also ships ready-made workflow prompts. These show up as slash commands in MCP clients (Claude Desktop, Cursor, Claude Code, Zed) so common tasks don't have to be re-prompted from scratch.
| Prompt | Description |
|---|---|
onboard_document |
Guided intake to add or update a passport, national ID, driving licence, or visa |
travel_preflight |
Check passport and visa validity for an upcoming trip |
selective_share |
Share the minimum a service actually needs, with an explicit consent purpose |
expiry_audit |
Surface anything expiring soon (metadata only, no consent prompts) |
Prompts don't access your data themselves. They tell the calling agent which Safehold tools to call, in what order, and with what purpose. Every retrieval still goes through the normal consent flow.
Skills
safehold-skills is a companion package of Claude Code skills that turn Safehold from a vault into finished workflows: airline check-in, ESTA applications, KYC forms, and so on. Each skill pairs Safehold with a browser MCP and asks for fields one at a time with a precise purpose string.
npx safehold-skills install
Quick Install
Requires Node.js >=20. No build step.
Most clients use the same JSON config — just the file path differs:
{
"mcpServers": {
"safehold": {
"command": "npx",
"args": ["-y", "safehold@latest"]
}
}
}
| Client | Config file |
|---|---|
| Claude Desktop (macOS) | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Claude Desktop (Windows) | %APPDATA%\Claude\claude_desktop_config.json |
| Cursor (project) | .cursor/mcp.json |
| Cursor (global) | ~/.cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| Amazon Q Developer (global) | ~/.aws/amazonq/mcp.json |
| Amazon Q Developer (project) | .amazonq/mcp.json |
Clients with slightly different config formats:
Claude Code (CLI)
claude mcp add safehold npx -- -y safehold@latest
VS Code (GitHub Copilot) — uses "servers" key, enable Agent mode in Copilot Chat. Edit .vscode/mcp.json (project) or ~/Library/Application Support/Code/User/mcp.json (global, macOS):
{
"servers": {
"safehold": {
"command": "npx",
"args": ["-y", "safehold@latest"]
}
}
}
Zed — uses "context_servers" key in ~/.config/zed/settings.json:
{
"context_servers": {
"safehold": {
"command": "npx",
"args": ["-y", "safehold@latest"]
}
}
}
OpenAI Codex CLI — TOML format in ~/.codex/config.toml:
[mcp_servers.safehold]
command = "npx"
args = ["-y", "safehold@latest"]
Continue.dev — create .continue/mcpServers/safehold.json (enable Agent mode):
{
"command": "npx",
"args": ["-y", "safehold@latest"]
}
Hermes (Nous Research) — YAML format in ~/.hermes/config.yaml:
mcp_servers:
safehold:
command: npx
args: ["-y", "safehold@latest"]
OpenClaw — uses "servers" key in ~/.openclaw/mcp.json:
{
"servers": {
"safehold": {
"command": "npx",
"args": ["-y", "safehold@latest"]
}
}
}
Roadmap
get_travel_authorization- ESTA, eTA, UK ETA, and similarget_vaccination_certificate- international vaccination recordsget_residency_permit- BRP, Green Card, and equivalentsget_birth_certificateget_tax_id- NI number, SSN, TFN, and equivalentsget_proof_of_address- utility bills, bank lettersget_travel_insurance
Development
npm install
npm test # run tests
npm run typecheck # type check
npm run build # compile to dist/
npm run dev # run directly with tsx (no build step)
Releasing
npm version patch # bug fix (0.1.0 → 0.1.1)
npm version minor # feature (0.1.0 → 0.2.0)
npm version major # breaking (0.1.0 → 1.0.0)
Checks that you're on a clean, up-to-date main branch, bumps the version, commits, tags, and pushes. CI publishes to npm.
Built by
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。
mcp-server-qdrant
这个仓库展示了如何为向量搜索引擎 Qdrant 创建一个 MCP (Managed Control Plane) 服务器的示例。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。