Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
제작자가 쓴 설명(영어 원문)
MCP server for Enpass vaults: entries, passwords and TOTP/2FA codes, keychain-backed.
이 세 가지는 절대 하나의 점수로 합치지 않아요. 의견, 측정, 인기는 서로 다른 것이니까요.
이 서버는 아직 쉬운 말로 된 요약을 쓰지 못했어요. 아래는 레지스트리에서 읽어 온 사실이에요.
쓰고 있는 AI 앱을 고른 다음 설정을 복사하세요.
필요한 것
어떤 앱을 쓰세요?
위에서 앱을 고르세요. 기억해 두었다가 다음부터는 버튼에 “…에 설치”라고 표시해요.
Claude Desktop → Settings → Developer → Edit Config를 열고 claude_desktop_config.json에 이 내용을 붙여 넣으세요
{
"mcpServers": {
"enpass": {
"command": "npx",
"args": [
"-y",
"enpass-mcp"
]
}
}
}터미널에서 이 명령어를 실행하세요
claude mcp add enpass -- npx -y enpass-mcp프로젝트의 .cursor/mcp.json 또는 ~/.cursor/mcp.json에 붙여 넣으세요
{
"mcpServers": {
"enpass": {
"command": "npx",
"args": [
"-y",
"enpass-mcp"
]
}
}
}브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.
프로젝트의 .vscode/mcp.json에 붙여 넣으세요
{
"servers": {
"enpass": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"enpass-mcp"
]
}
}
}브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.
이 서버는 내 컴퓨터에서 실행되는데, ChatGPT는 인터넷에 있는 서버에만 연결할 수 있어요. 다른 앱을 고르세요.
선택한 앱은 이 기기의 쿠키에만 저장돼요. 계정은 필요 없어요.
이 설정은 제작자의 레지스트리 정보로 만들었어요. README와 다르면 README를 따르세요.
내 컴퓨터에서 실행돼요. 설치하면 AI 앱에 도구 목록이 나타나요.
누구나 볼 수 있는 정보를 점검했고, 코드는 읽지 않았어요. 해당하지 않는 항목은 개수에서 뺐어요. · 2026년 11월 6일 점검
레지스트리 이름이 GitHub 계정 bitterdev 기준으로 확인되었고, 이 계정이 저장소를 소유하고 있어요
아직 GitHub에서 이 저장소를 읽어 오지 않았어요
아직 GitHub에서 이 저장소를 읽어 오지 않았어요
내 컴퓨터에서 실행되는 서버라 인터넷 엔드포인트가 없어요
내 컴퓨터에서 실행되며, 대신 로컬 설정을 사용해요
내 컴퓨터에서 실행돼요. 도구 목록은 인터넷 엔드포인트가 있는 서버에서만 읽을 수 있어요
레지스트리에서 이 카테고리의 활성 서버 전체와 비교했어요. 스타는 게시자가 저장소를 소유한 경우에만 세요.
해당하는 기본 점검 1개 중 1개를 통과했어요. 코드는 읽지 않았어요. 키나 토큰을 넣기 전에 서버가 어떤 권한을 요구하는지 확인하고, 꼭 필요한 권한만 있는 키를 쓰세요.
레지스트리에 필수 키가 나와 있지 않아요. 다만 처음 쓸 때 로그인을 요구하는 서버도 있어요.
내 컴퓨터에서 실행돼요. AI 앱이 필요할 때 실행하고, 데이터는 제작자의 서버를 거치지 않아요(서버 자체가 온라인 서비스를 호출하는 경우는 제외).
GitHub 저장소는 마지막으로 – 변경됐고, 최신 버전(0.1.0)은 4개월 전 레지스트리에 올라왔어요.
Claude Desktop, Claude Code, Cursor, VS Code처럼 MCP를 지원하는 앱에서 쓸 수 있어요. 내 컴퓨터에 Node.js도 있어야 해요.
같은 카테고리에는: Spec Driven Development, Remote Desktop Commander, Binggio
같은 카테고리에서 다른 제작자가 만든 서버예요. 스타 순으로 정렬했어요.
카드 보는 법:★ GitHub 스타i세 기둥: 리뷰 · 점검 · 사용 정도i업데이트 = 최신 버전을 레지스트리에 공개한 날i
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Governed answers from your data: approved meanings only, refusals instead of guesses.
제작자의 저장소에서 쓰인 그대로 가져왔어요. PopNx MCP가 검토하거나 보증한 내용이 아니에요. HTML, 이미지, 스크립트는 제거했어요. 링크를 누르면 이 사이트를 벗어나요.
A Model Context Protocol (MCP) server that gives an AI assistant controlled, local access to your Enpass password vaults: unlock a vault, list vaults, and list and read entries. Creating and deleting entries is possible too, but switched off until you enable it.
Runs locally over stdio. Your Enpass vault never leaves your machine, and your master password never passes through the model: it is stored in your operating system's keychain and read directly by the server.
unlock_vault tool deliberately takes no password parameter, so the password can never end up in the model's context or in logs.vault.enpassdb file directly with SQLCipher. Nothing is uploaded anywhere.get_item / get_password, when you explicitly ask for them.ENPASS_MCP_ALLOW_WRITES=1 to enable them (see Writing).Entry passwords are, by design, returned to the assistant when you ask for them, so only connect this to an assistant and vaults you trust.
vault.enpassdb, SQLCipher format)Native dependencies (better-sqlite3-multiple-ciphers, @napi-rs/keyring) ship prebuilt binaries for common platforms, so no compiler is required in the normal case.
git clone https://github.com/bitterdev/enpass-mcp.git
cd enpass-mcp npm install npm link # optional: makes the enpass-mcp command available globally
This is the secure step that keeps the master password away from the model. You run it yourself; the password is typed into a hidden prompt and stored in the OS keychain.
# Find your vault files automatically
enpass-mcp discover
enpass-mcp add-vault personal --path "/Users/you/Documents/Enpass/Vaults/primary/vault.enpassdb" enpass-mcp add-vault work --path "/path/to/work/vault.enpassdb"
enpass-mcp add-vault personal --path "/path/vault.enpassdb" --keyfile "/path/vault.keyfile"
enpass-mcp list-vaults enpass-mcp test-unlock personal enpass-mcp remove-vault work
add-vault verifies the password can actually unlock the vault before saving it.
The vault file is usually found at:
| OS | Typical location |
|---|---|
| macOS | ~/Documents/Enpass/Vaults/ /vault.enpassdb |
| Windows | %USERPROFILE%\Documents\Enpass\Vaults\ \vault.enpassdb |
| Linux | ~/Documents/Enpass/Vaults/ /vault.enpassdb |
If you sync via Dropbox / OneDrive / WebDAV, point --path at the synced copy.
The server speaks MCP over stdio. Point your MCP client at enpass-mcp serve.
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": { "enpass": { "command": "enpass-mcp", "args": ["serve"] } } }
If you did not run npm link, use the absolute path instead:
{
"mcpServers": { "enpass": { "command": "node", "args": ["/absolute/path/to/enpass-mcp/src/cli.js", "serve"] } } }
Claude Code:
claude mcp add enpass -- enpass-mcp serve
| Tool | Description |
|---|---|
list_vaults | List registered vaults, whether their file exists, whether a password is stored, and whether they are unlocked. |
unlock_vault | Unlock a vault using the master password from the OS keychain. Takes only a vault name, never a password. |
lock_vault | Lock a vault and clear its derived key from memory. |
list_items | List entries (title, username, URL). Never returns passwords. Supports query, category, folder, limit. |
get_item | Return a full entry including all field values (password, TOTP, etc.) and its attachment list. |
get_password | Return the password and, if present, the current TOTP code of an entry. |
get_otp | Generate the current TOTP / 2FA one-time code for an entry, with seconds until it rotates. |
list_attachments | List an entry's file attachments (name, size, MIME). |
export_attachment | Decrypt an attachment; writes it to disk and returns the path (or base64 inline for small files). |
sync_status | List the vaults that use Enpass folder sync and whether the copy in the sync folder is newer. |
With ENPASS_MCP_ALLOW_WRITES=1 three more tools appear (see Writing):
| Tool | Description |
|---|---|
create_item | Create an entry, including custom fields; sensitive values are encrypted the way Enpass does it. |
delete_item | Delete an entry, or move it to the trash, leaving the tombstone Enpass uses so the deletion syncs. |
sync_pull | Take in a newer copy from the sync folder, after backing up the local vault. |
list_items / get_item work for every Enpass entry type (logins, credit cards, secure notes, identities, etc.), not just logins, and return all fields.
A typical assistant flow: list_vaults → unlock_vault → list_items → get_password.
Enpass stores each vault as a standard SQLCipher database (vault.enpassdb). The raw encryption key is derived from your master password (optionally combined with a keyfile) and the 16-byte salt at the start of the file:
cipher_compatibility 4 (Enpass 6.8+) or 3 (older vaults)The server tries these combinations automatically, so it works across Enpass vault versions. The derived key is kept in memory only, for the lifetime of the server process, and is never written to disk or returned to the model.
References: Enpass Security Whitepaper, hazcod/enpass-cli.
Enpass encrypts every value flagged as "sensitive" a second time, underneath SQLCipher, with a key that belongs to the entry rather than the vault. Fields carrying that layer have itemfield.algo_version = 1:
| Piece | Where | Layout | ||
|---|---|---|---|---|
| Key and nonce | item.key | 44 bytes: 32-byte AES-256 key, then a 12-byte GCM nonce | ||
| Value | itemfield.value | hex of `ciphertext \ | \ | 16-byte GCM tag` |
| Additional data | the entry's uuid | hyphens stripped, hex-decoded to 16 raw bytes |
Binding the AAD to the entry uuid is what makes a value unusable if it is copied into another entry. Enpass did not re-encrypt existing entries when it introduced this layer, so one vault mixes ciphertext and plaintext under the same algo_version; a value is treated as encrypted only when it has the shape of a payload (pure hex, whole bytes, longer than the tag on its own).
A value that looks encrypted but fails authentication is returned as null with decryptionFailed: true, never as the raw column content: stored ciphertext is a plausible-looking string, and handing that back would silently pass off a wrong secret as a real one.
Entries with a one-time-password secret (stored by Enpass as an otpauth:// URI) can produce a live 2FA code: get_otp returns the current 6-digit code and the seconds until it rotates, and get_password includes the current code alongside the password. This lets an assistant fill both the password and the 2FA prompt.
Enpass keeps file attachments encrypted. Small files (up to 1 KB) sit inline in the vault; larger files live in separate .enpassattach SQLCipher files next to the vault, each encrypted with its own key stored in the vault. export_attachment handles both: it decrypts the file and, by default, writes it to disk and returns the path, so it works for files of any size without pushing binary data through the model.
Two details of that format are easy to miss, and both were wrong here until they were measured against real vaults:
attachment.password is not a key blob. It holds the finished SQLCipher raw-key expression as text, x'<64 hex key chars><32 hex salt chars>', and has to be passed through verbatim. Hex-encoding it produces a key SQLCipher rejects, and every external attachment then fails with "file is not a database".data:application/pdf;base64,...) rather than the file itself, so it has to be decoded. Writing those bytes straight to disk yields a text file with a .pdf name. attachment.size counts the stored bytes, which is why it is larger than the exported file for anything wrapped this way.If you hit a vault whose attachments still do not decrypt, please open an issue with the (non-secret) schema of your attachment table.
Attachments also do not travel inside the folder-sync container: Enpass drops the .enpassattach files into the sync folder next to it. sync_pull fetches the ones this machine is missing, and publishing a write copies local ones the sync folder lacks. Existing files are never overwritten or removed in either direction.
Writing is switched off by default. A password vault is the last place where a tool should be able to change data just because a model decided to, so the server starts read-only and does not even list create_item, delete_item, add_attachment and sync_pull until you turn them on:
ENPASS_MCP_ALLOW_WRITES=1
Set it in the server's environment (in your MCP client config, or in the .env next to vaults.json). Nothing else changes: reading works exactly the same either way.
Enpass must be closed while writing. The app keeps the database in memory and would write its own cached copy back over any change made underneath it. Every writing tool refuses to run while Enpass is open.
Earlier versions of this README claimed writing was impossible because recent vaults (schema version 6) crash Enpass when entries are inserted directly. The crash was real, the diagnosis was wrong. Three concrete rules make it work, all of them derived from what Enpass itself writes:
EXC_BAD_ACCESS in strlen on a null pointer: a column omitted from the INSERT defaults to NULL, and the app calls strlen on it. Every column is written explicitly, empty strings instead of NULL.login.default always carries the same nine fields, in the same order, with the same field uids, even when most are empty. Writing only the fields you happen to have a value for produces an entry the app cannot render.item.key is a 32-byte AES-256 key plus a 12-byte GCM nonce, stored as hex(ciphertext || tag) with the item UUID as additional authenticated data. Nothing in it is tied to Enpass internals, so a fresh random key per item is fine.Verified end to end against a real vault: written, read back, decrypted to the original, deleted, synced in both directions, and Enpass opens the vault without crashing.
add_attachment takes a path, never base64 in the argument list, and stores the bytes raw in the attachment's own encrypted database. Two rules come out of the same format details as readin
앞부분만 보여 드려요. 나머지는 저장소에서 읽어 보세요