Skip to main content
Glama
aureTheDev

protonpass-mcp

by aureTheDev
README.md
# protonpass-mcp

A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for [Proton Pass](https://proton.me/pass). It wraps the official [`pass-cli`](https://protonpass.github.io/pass-cli/) binary and exposes 14 tools so any MCP-compatible AI assistant (Claude Desktop, Claude Code, etc.) can manage your vaults, credentials, and secrets.

> **Note:** Proton Pass has no public REST API. This server uses the official `pass-cli` binary under the hood. The CLI is currently in beta and requires a **Visionary or higher** Proton plan.

---

## Table of contents

- [Features](#features)
- [Requirements](#requirements)
- [Project structure](#project-structure)
- [Quick start (Docker)](#quick-start-docker)
  - [1. Build the image](#1-build-the-image)
  - [2. Authenticate](#2-authenticate)
  - [3. Configure your MCP client](#3-configure-your-mcp-client)
- [Running without Docker](#running-without-docker)
- [Available tools](#available-tools)
- [Environment variables](#environment-variables)
- [Security considerations](#security-considerations)
- [Troubleshooting](#troubleshooting)

---

## Features

- **Vault management** — list, create, share vaults
- **Item management** — list, view, create (login / note), update, trash, restore
- **TOTP** — read live 2FA codes from stored items
- **Secret references** — retrieve any field via `pass://Vault/Item/field` URIs
- **Password generation** — generate cryptographically secure passwords
- **Account info** — inspect the currently authenticated Proton account
- **Dockerized** — no local Node.js or `pass-cli` installation required on the host
- **Persistent sessions** — session tokens survive container restarts via a named Docker volume

---

## Requirements

| Dependency | Version |
|---|---|
| Docker | 24+ |
| Proton Pass account | Visionary plan or higher (CLI beta requirement) |

No Node.js, npm, or `pass-cli` installation is needed on your host machine — everything runs inside the Docker image.

---

## Project structure

```
protonpass-mcp/
├── src/
│   └── index.ts          # MCP server — tool definitions and handlers
├── Dockerfile            # Multi-stage build (TypeScript → runtime + pass-cli)
├── docker-compose.yml    # Optional: run via Compose
├── mcp-config.json       # MCP client configuration snippet
├── .env.example          # Environment variable template
├── package.json
└── tsconfig.json
```

---

## Quick start (Docker)

### 1. Build the image

```bash
docker build -t protonpass-mcp .
```

The build installs Node.js, downloads and installs `pass-cli` from Proton's official installer, compiles the TypeScript source, and produces a minimal runtime image.

### 2. Authenticate

The MCP server is non-interactive. Run this once to log in and save the session to the named Docker volume:

```bash
docker run --rm -it \
  -e PROTON_PASS_KEY_PROVIDER=fs \
  -v protonpass-session:/root/.local/share/proton-pass-cli \
  --entrypoint pass-cli \
  protonpass-mcp:latest login --interactive
```

Enter your Proton credentials (email, password, TOTP if enabled) when prompted. The session token and encryption key are written to the `protonpass-session` volume and reused automatically on every subsequent server start.

To verify the session is working:

```bash
docker run --rm \
  -e PROTON_PASS_KEY_PROVIDER=fs \
  -v protonpass-session:/root/.local/share/proton-pass-cli \
  --entrypoint pass-cli \
  protonpass-mcp:latest user info
```

> **Windows (cmd / PowerShell):** Replace `\` line continuations with `^` (cmd) or `` ` `` (PowerShell), or write the command on a single line.

> **Tip:** Re-run the login command if your session expires.

### 3. Configure your MCP client

Copy the contents of [mcp-config.json](mcp-config.json) into your client's configuration file.

**Claude Desktop** (`claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "protonpass": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-e", "PROTON_PASS_KEY_PROVIDER=fs",
        "-e", "PASS_LOG_LEVEL=warn",
        "-v", "protonpass-session:/root/.local/share/proton-pass-cli",
        "protonpass-mcp:latest"
      ]
    }
  }
}
```

**Claude Code** (`~/.claude/settings.json`):

```json
{
  "mcpServers": {
    "protonpass": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-e", "PROTON_PASS_KEY_PROVIDER=fs",
        "-e", "PASS_LOG_LEVEL=warn",
        "-v", "protonpass-session:/root/.local/share/proton-pass-cli",
        "protonpass-mcp:latest"
      ]
    }
  }
}
```

After saving the config, restart your MCP client. The server starts automatically on demand — Docker launches a fresh container for every session and removes it when done (`--rm`).

---

## Running without Docker

If `pass-cli` and Node.js (v22+) are already installed on your machine:

```bash
npm install
npm run build
node dist/index.js
```

Configure your MCP client to run `node /path/to/protonpass-mcp/dist/index.js` directly.

---

## Available tools

| Tool | Description | Required params |
|---|---|---|
| `list_vaults` | List all accessible vaults | — |
| `create_vault` | Create a new vault | `name` |
| `list_items` | List items (all vaults or filtered) | — |
| `view_item` | View full item details including credentials | `item_id`, `vault_id` |
| `create_login` | Create a login credential item | `vault_id`, `title` |
| `create_note` | Create a secure note item | `vault_id`, `title`, `note` |
| `update_item` | Update fields of an existing item | `item_id`, `vault_id` |
| `trash_item` | Move an item to trash (soft delete) | `item_id`, `vault_id` |
| `restore_item` | Restore a trashed item | `item_id`, `vault_id` |
| `get_totp` | Get the current live TOTP code | `item_id`, `vault_id` |
| `generate_password` | Generate a secure random password | — |
| `view_secret` | Read a field via `pass://` URI | `uri` |
| `get_user_info` | Show authenticated account details | — |
| `share_vault` | Share a vault with another Proton user | `vault_id`, `email`, `role` |

### Secret URI format

The `view_secret` tool accepts `pass://` URIs identifying any field of any item:

```
pass://<vault-name>/<item-name>/<field>
```

Built-in fields: `username`, `password`, `email`, `url`, `note`, `totp`.
Custom fields are addressed by their exact name (case-sensitive).

**Examples:**

```
pass://Work/GitHub/password
pass://Personal/Netflix/username
pass://Servers/Production DB/note
```

### Vault sharing roles

| Role | Permissions |
|---|---|
| `manager` | Read, write, share |
| `editor` | Read, write |
| `viewer` | Read-only |

---

## Environment variables

| Variable | Default | Description |
|---|---|---|
| `PROTON_PASS_KEY_PROVIDER` | `keyring` | Key storage backend. Use `fs` in Docker (no system keyring). |
| `PROTON_PASS_ENCRYPTION_KEY` | — | Encryption key when `KEY_PROVIDER=env`. SHA-256 hashed internally. |
| `PROTON_PASS_SESSION_DIR` | platform default | Override session storage path. |
| `PASS_LOG_LEVEL` | `info` | Log verbosity: `trace`, `debug`, `info`, `warn`, `error`, `off`. |

When using Docker Compose, copy `.env.example` to `.env` and edit the values — Compose picks it up automatically:

```bash
cp .env.example .env
```

Otherwise, set them in [docker-compose.yml](docker-compose.yml) or in the `args` array of your MCP client config.

---

## Security considerations

- **Session volume:** The `protonpass-session` Docker volume contains your Proton Pass session token and (when using `PROTON_PASS_KEY_PROVIDER=fs`) your encryption key. Treat it with the same care as a private key file. Back it up securely.
- **`PROTON_PASS_ENCRYPTION_KEY`:** If you set this variable, do not store it in version-controlled files. Pass it via a secrets manager or a `.env` file excluded from git.
- **Command injection:** The server uses `execFile` with argument arrays — no shell interpolation occurs. User-supplied strings are passed as discrete arguments, not interpolated into a shell command.
- **No secrets in tool output:** `view_item` and `view_secret` return whatever `pass-cli` outputs. Ensure your MCP client does not log tool results to untrusted locations.
- **Container isolation:** Each MCP session spawns an isolated container (`--rm`). The container has no network access beyond what Docker grants by default and no host filesystem access beyond the named session volume.

---

## Troubleshooting

**`Error: pass-cli: command not found`**
The image was not built with the Proton installer. Rebuild with `docker build --no-cache -t protonpass-mcp .`.

**`Error: no session found` / `Error: not authenticated`**
Re-run the authentication command from step 2. The session may have expired.

**`Error: permission denied on volume`**
Ensure the `protonpass-session` volume was created by Docker and is accessible. Run `docker volume inspect protonpass-session` to verify.

**`pass-cli` hangs on login inside the container**
The `--interactive` flag is required for terminal-based login. Make sure it is present in the `docker run` command.

**Items return IDs but you need names**
Use `list_vaults` to get vault share IDs, then `list_items` with that `vault_id` to get item IDs. The `view_secret` tool accepts human-readable names via the `pass://` URI syntax.

TDQS

A3.7/5.0

Scored across 14 tools

Disambiguation4/5

Each tool targets a specific resource and action, with only minor overlap between get_totp and view_secret (which can retrieve the totp field via URI). For example, list_items vs view_item are clearly distinct in scope (metadata vs full details).

Naming Consistency5/5

All tools follow a consistent verb_noun snake_case pattern (e.g., list_vaults, create_note, trash_item, generate_password). There is no mixing of camelCase, vague verbs, or irregular naming conventions.

Tool Count5/5

14 tools is well-scoped for a password manager, covering vaults, items, lifecycle, sharing, TOTP, and password generation. Each tool has a distinct place and the set feels intentional rather than bloated.

Completeness4/5

The tool surface covers core CRUD/lifecycle for vaults and items, plus sharing, TOTP retrieval, and password generation. Minor gaps exist, such as no permanent delete (only trash/restore) and limited item creation types (only login and note), but these are workable.

Maintenance

ActivityInactive
ResponsivenessNo issues