# Unix pass (pypi · unix-pass-mcp)

Local MCP access to Unix pass/GPG with read-only defaults, path scopes, and TOTP.

- Trust score: 63/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- pypi · `unix-pass-mcp`: 63/100 (this document), [markdown](https://verifymcp.io/servers/neanderthal-unix-pass-mcp/unix-pass-mcp.md), [page](https://verifymcp.io/servers/neanderthal-unix-pass-mcp/unix-pass-mcp)

## Channel facts

- Registry: `pypi`
- Package: `unix-pass-mcp`
- Version: `0.2.1`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Supply Chain Security**: 50/100
  - Malware scan not yet available for this package.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised build step with no custom scripting around it.
  - 1 of 28 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to Neanderthal/unix-pass-mcp).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 1 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 72/100
  - AI-judged instruction clarity (good).
  - Tool/resource definitions use about 2410 tokens (~100/item across 24 items; 24 tools + 0 resources), lean.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 71/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 25 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### How do I install the Unix pass MCP server?

Unix pass runs locally as a PyPI package, launched with uvx unix-pass-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add neanderthal-unix-pass-mcp -- uvx unix-pass-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "neanderthal-unix-pass-mcp": {
      "command": "uvx",
      "args": [
        "unix-pass-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "neanderthal-unix-pass-mcp": {
      "command": "uvx",
      "args": [
        "unix-pass-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add neanderthal-unix-pass-mcp -- uvx unix-pass-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "neanderthal-unix-pass-mcp": {
      "type": "local",
      "command": [
        "uvx",
        "unix-pass-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add neanderthal-unix-pass-mcp --command uvx --arg unix-pass-mcp
```

### Hermes

```yaml
mcp_servers:
  neanderthal-unix-pass-mcp:
    command: "uvx"
    args: ["unix-pass-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "neanderthal-unix-pass-mcp": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "unix-pass-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add neanderthal-unix-pass-mcp -t stdio -c uvx -a unix-pass-mcp
```

### Other

```json
{
  "mcpServers": {
    "neanderthal-unix-pass-mcp": {
      "command": "uvx",
      "args": [
        "unix-pass-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-04 (score 63)

First indexed and scored.

## MCP tools (24)

### `store_info` (~59 tokens)

Inspect the configured password store without decrypting anything. Returns store path, recipient keys per subdirectory (from .gpg-id files), git/agent/signing status, and any configuration warnings. Call this first to confirm the store is reachable and healthy.

Output parameters:

- `exists` (boolean)
- `git_remotes` (array)
- `gpg_agent_available` (boolean)
- `is_git_repo` (boolean)
- `pass_version`
- `pinentry`
- `recipients_by_subdir` (object)
- `signing_key_fingerprints` (array)
- `signing_required` (boolean)
- `store_dir` (string)
- `umask` (string)
- `warnings` (array)

### `list` (~50 tokens)

List all pass-names (entries) in the store, optionally scoped to a subfolder. Returns a flat sorted list of names without the .gpg suffix. Does not decrypt.

Input parameters:

- `subfolder`

Output parameters:

- `count` (integer)
- `names` (array)
- `query` (string)
- `subfolder`

### `find` (~46 tokens)

Find pass-names whose leaf name contains `query` (case-insensitive substring). Mirrors `pass find`. Does not decrypt.

Input parameters:

- `query` (string, required)
- `subfolder`

Output parameters:

- `count` (integer)
- `names` (array)
- `query` (string)
- `subfolder`

### `show` (~101 tokens)

Decrypt and return the password (line 1) for a pass-name. Pass `line` to return a different line (1-indexed). The returned `value` is sensitive. Use it only for the user's explicitly requested task; never quote or repeat it in assistant messages, summaries, logs, or unrelated tool calls. Avoid retrieving it unless necessary. Clients should not log or cache it.

Input parameters:

- `line` (integer)
- `name` (string, required)

Output parameters:

- `line` (integer)
- `sensitive` (boolean)
- `value` (string)

### `show_field` (~103 tokens)

Decrypt the entry and return one named metadata field (e.g. `URL`, `Username`, `otpauth`). Field lookup is case-insensitive. Returns null `value` if the field is absent. The password line is never returned. Field values may be secrets: use only for the requested task and never quote or repeat them in assistant messages, summaries, logs, or unrelated tool calls.

Input parameters:

- `field` (string, required)
- `name` (string, required)

Output parameters:

- `field` (string)
- `present` (boolean)
- `sensitive` (boolean)
- `value`

### `unlock_agent` (~231 tokens)

\**Call this whenever any other tool returns `agent_unavailable`** — that error means gpg-agent is up but pinentry can't prompt (typically pinentry-curses + no TTY, the default deadlock when an MCP server is spawned by Claude Desktop/Code). This tool resolves it: pops a desktop password dialog (zenity / kdialog) and decrypts one entry via loopback pinentry. After it succeeds, subsequent `show`/`grep`/etc calls work without TTY-bound pinentry until the agent's cache TTL expires (default 600s, set via `default-cache-ttl` in ~/.gnupg/gpg-agent.conf). Do NOT ask the user to paste their GPG passphrase into chat — the passphrase travels desktop dialog → our process → gpg stdin and the LLM never sees it. Optional `target` is a pass-name to decrypt against (useful when the store has multiple `.gpg-id` recipients and you want to warm a specific key); without it, the smallest in-scope entry is used.

Input parameters:

- `target`

Output parameters:

- `dialog` (string)
- `method` (string)
- `ok` (boolean)
- `reason` (string)
- `warmup_target_size_bytes` (integer)

### `show_metadata` (~54 tokens)

Decrypt the entry but return only its shape: which metadata field names exist, whether a password is present, and the raw line count. Useful to inspect entry structure without surfacing the password.

Input parameters:

- `name` (string, required)

Output parameters:

- `field_names` (array)
- `name` (string)
- `password_present` (boolean)
- `raw_lines` (integer)

### `insert` (~80 tokens)

Create or overwrite a single-line entry. The password is passed via stdin (never argv) so it never appears in /proc/<pid>/cmdline. Refuses if the entry exists unless `force=true`. Requires PASS_MCP_ALLOW_WRITES=1.

Input parameters:

- `force` (boolean)
- `name` (string, required)
- `password` (string, required)

Output parameters:

- `bytes` (integer)
- `name` (string)
- `ok` (boolean)
- `replaced` (boolean)

### `insert_multiline` (~93 tokens)

Create or overwrite a multi-line entry. Line 1 is the password; subsequent lines should follow `Key: value` convention (URL, Username, otpauth, …). Body is passed via stdin. Refuses if the entry exists unless `force=true`. Requires PASS_MCP_ALLOW_WRITES=1.

Input parameters:

- `body` (string, required)
- `force` (boolean)
- `name` (string, required)

Output parameters:

- `bytes` (integer)
- `name` (string)
- `ok` (boolean)
- `replaced` (boolean)

### `set_field` (~165 tokens)

Set or update one `Key: value` metadata field on an existing entry, preserving the password and all other lines. Field lookup is case-insensitive; existing case is preserved on update, new fields are appended in the requested case. Refuses if the entry does not exist (use `insert_multiline` to create). Pass `simulate=true` to compute the would-be body without writing — useful for agent dry-runs. Requires PASS_MCP_ALLOW_WRITES=1 (also for simulate). Simulated bodies contain the password and other entry data; never quote or repeat them in assistant messages, summaries, logs, or unrelated tool calls.

Input parameters:

- `field` (string, required)
- `name` (string, required)
- `simulate` (boolean)
- `value` (string, required)

Output parameters:

- `after` (string)
- `before` (string)
- `changed` (boolean)
- `field` (string)
- `fields_count` (integer)
- `name` (string)
- `ok` (boolean)
- `removed` (boolean)
- `sensitive` (boolean)
- `simulated` (boolean)

### `unset_field` (~108 tokens)

Remove all lines matching `field` (case-insensitive) from an existing entry, preserving the password and all other lines. No-op if the field is absent. Pass `simulate=true` for a dry-run. Simulated bodies contain secret entry data; never quote or repeat them in assistant messages, summaries, logs, or unrelated tool calls. Requires PASS_MCP_ALLOW_WRITES=1.

Input parameters:

- `field` (string, required)
- `name` (string, required)
- `simulate` (boolean)

Output parameters:

- `after` (string)
- `before` (string)
- `changed` (boolean)
- `field` (string)
- `fields_count` (integer)
- `name` (string)
- `ok` (boolean)
- `removed` (boolean)
- `sensitive` (boolean)
- `simulated` (boolean)

### `generate` (~170 tokens)

Generate a new password for `name`. `length` defaults to PASSWORD_STORE_GENERATED_LENGTH (or 25). `no_symbols=true` restricts to alphanumerics. `in_place=true` replaces only the first line of an existing entry (preserving metadata) and needs the entry to exist. `force=true` overwrites any existing entry from scratch. Without either flag, refuses if the entry already exists. Returns a sensitive generated password; use only for the requested task and never quote or repeat it in assistant messages, summaries, logs, or unrelated tool calls. Requires PASS_MCP_ALLOW_WRITES=1.

Input parameters:

- `force` (boolean)
- `in_place` (boolean)
- `length` (integer)
- `name` (string, required)
- `no_symbols` (boolean)

Output parameters:

- `in_place` (boolean)
- `length` (integer)
- `name` (string)
- `no_symbols` (boolean)
- `sensitive` (boolean)
- `value` (string)

### `otp` (~100 tokens)

Compute the current TOTP code for an entry containing an `otpauth://` line (pass-otp / browserpass convention). Returns the code plus `seconds_remaining` in the current window — if it's very low (<5s), wait for the next window before submitting. The code is sensitive: use only for the requested task and never quote or repeat it in assistant messages, summaries, logs, or unrelated tool calls.

Input parameters:

- `name` (string, required)

Output parameters:

- `account`
- `algorithm` (string)
- `code` (string)
- `digits` (integer)
- `issuer`
- `period` (integer)
- `seconds_remaining` (integer)
- `sensitive` (boolean)

### `otp_uri` (~88 tokens)

Return the raw `otpauth://` URI stored on the entry (contains the secret). Use this only when you need to re-enroll the same secret elsewhere; for submitting a code, prefer `otp`. The URI is sensitive: use only for the requested task and never quote or repeat it in assistant messages, summaries, logs, or unrelated tool calls.

Input parameters:

- `name` (string, required)

Output parameters:

- `name` (string)
- `sensitive` (boolean)
- `uri` (string)

### `otp_set` (~78 tokens)

Add or replace the `otpauth://` URI on an existing entry, preserving the password and all other lines. The URI is validated before write. Refuses if the entry does not exist (use `insert` first). Requires PASS_MCP_ALLOW_WRITES=1.

Input parameters:

- `name` (string, required)
- `uri` (string, required)

Output parameters:

- `bytes` (integer)
- `name` (string)
- `ok` (boolean)
- `replaced` (boolean)

### `mv` (~72 tokens)

Rename or move an entry/subfolder. Re-encrypts to the destination subfolder's recipients if they differ. Refuses if the destination exists unless `force=true`. Requires PASS_MCP_ALLOW_WRITES=1.

Input parameters:

- `dst` (string, required)
- `force` (boolean)
- `src` (string, required)

Output parameters:

- `dst` (string)
- `ok` (boolean)
- `src` (string)

### `cp` (~70 tokens)

Copy an entry/subfolder. Re-encrypts to the destination subfolder's recipients if they differ. Refuses if the destination exists unless `force=true`. Requires PASS_MCP_ALLOW_WRITES=1.

Input parameters:

- `dst` (string, required)
- `force` (boolean)
- `src` (string, required)

Output parameters:

- `dst` (string)
- `ok` (boolean)
- `src` (string)

### `grep` (~124 tokens)

Search inside permitted entries for a basic regular expression pattern. **Slow and expensive** — decrypts permitted entries, warming their secret keys in gpg-agent's cache. Caller must pass `confirm_decrypt_all=true` to acknowledge. Returns matched lines (sensitive — they're decrypted content). Never quote or repeat matched content in assistant messages, summaries, logs, or unrelated tool calls. Honours PASS_MCP_GREP_TIMEOUT_SECONDS (default 120s).

Input parameters:

- `case_insensitive` (boolean)
- `confirm_decrypt_all` (boolean)
- `pattern` (string, required)

Output parameters:

- `case_insensitive` (boolean)
- `count` (integer)
- `matches` (array)
- `pattern` (string)
- `redacted_entries` (integer)
- `sensitive` (boolean)

### `git_status` (~58 tokens)

Inspect git state of the password store. Returns whether the working tree is clean, current branch, upstream, ahead/behind counts, and any dirty paths. Refuses if the store is not a git repository (run `pass git init` first).

Output parameters:

- `ahead` (integer)
- `behind` (integer)
- `branch`
- `clean` (boolean)
- `dirty_files` (array)
- `upstream`

### `git_log` (~52 tokens)

Return recent commits in the password store as `[{hash, subject}, ...]`. `limit` defaults to 20 (max 200). Useful for auditing what changed and when.

Input parameters:

- `limit` (integer)

Output parameters:

- `commits` (array)
- `count` (integer)

### `git_pull` (~77 tokens)

Sync remote commits into the local store via `git pull --ff-only` (no merge commits, no rebase — refuses if local has diverged). Requires PASS_MCP_ALLOW_NETWORK=1 because it reaches out to a remote. Returns `{ok, output, stderr}`. On failure the agent should call `git_status` to diagnose.

Output parameters:

- `ok` (boolean)
- `output` (string)
- `stderr` (string)

### `git_push` (~40 tokens)

Push local commits to the configured upstream. Requires PASS_MCP_ALLOW_NETWORK=1. Returns `{ok, output, stderr}`. Does not force-push.

Output parameters:

- `ok` (boolean)
- `output` (string)
- `stderr` (string)

### `init` (~148 tokens)

Initialize the password store (or a subfolder) with the given GPG recipient(s). Re-encrypts every existing entry in scope to the new recipient set — this is DESTRUCTIVE. Pass an empty `gpg_ids` list to remove the .gpg-id file for the subfolder (entries inherit the parent's recipients). Refuses if the user has no secret key for any of the new recipients (would lock the user out); pass `force=true` to override (e.g. team scenarios where you're delegating access). Requires PASS_MCP_ALLOW_DESTRUCTIVE=1.

Input parameters:

- `force` (boolean)
- `gpg_ids` (array, required)
- `subfolder`

Output parameters:

- `gpg_ids` (array)
- `ok` (boolean)
- `removed` (boolean)
- `subfolder`

### `reencrypt` (~105 tokens)

Re-run `pass init` against the *current* `.gpg-id` recipients (no key change). Use after subkey rotation or to repair a store where some files are encrypted to outdated recipients. Note: `pass init` is a no-op when each file's existing recipients already match the .gpg-id — there is no way to force a fresh ciphertext without changing the recipient set. Requires PASS_MCP_ALLOW_DESTRUCTIVE=1.

Input parameters:

- `subfolder`

Output parameters:

- `gpg_ids` (array)
- `ok` (boolean)
- `removed` (boolean)
- `subfolder`

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/neanderthal-unix-pass-mcp/unix-pass-mcp#diagnostics

## Score history

- 2026-11-05: 63
- 2026-11-04: 63

## Common questions

### What is the Unix pass MCP server?

Unix pass is an MCP server listed in the public MCP registry as io.github.Neanderthal/unix-pass-mcp. Local MCP access to Unix pass/GPG with read-only defaults, path scopes, and TOTP. This page covers its PyPI package (unix-pass-mcp).

### Is the Unix pass MCP server safe to use?

Unix pass scores 63 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Unix pass MCP server expose?

Unix pass exposes 24 tools: store_info, list, find, show, show_field, and 19 more. Their descriptions and schemas cost roughly 2,272 tokens of context every time the server is loaded.

### Is the Unix pass MCP server still maintained?

Unix pass is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Unix pass MCP server under?

Unix pass declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- PyPI project: https://pypi.org/project/unix-pass-mcp/
- Socket report: https://socket.dev/pypi/package/unix-pass-mcp
- Repository: https://github.com/Neanderthal/unix-pass-mcp
- Changelog RSS feed: https://verifymcp.io/servers/neanderthal-unix-pass-mcp/unix-pass-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/neanderthal-unix-pass-mcp/unix-pass-mcp.json
- HTML version of this page: https://verifymcp.io/servers/neanderthal-unix-pass-mcp/unix-pass-mcp
