An open API service indexing awesome lists of open source software.

https://github.com/e4c6/keepassxc-dbus-mcp

KeePassXC Secret Service MCP server for credentials (KeePassXC D-Bus MCP)
https://github.com/e4c6/keepassxc-dbus-mcp

credentials dbus keepassxc mcp python secret-service security

Last synced: 5 months ago
JSON representation

KeePassXC Secret Service MCP server for credentials (KeePassXC D-Bus MCP)

Awesome Lists containing this project

README

          

# keepassxc-dbus-mcp

## At a Glance
- Helps your agent manage credentials (including ssh keypairs) in a KeePassXC DB group
- Provides tools:
- `get_credential_detail`
- `get_credential_secret`
- `get_credential_secret_as_temp_file`
- `create_credential`
- `update_credential`
- `delete_credential`
- `list_credentials`
- `search_credentials`
- `create_keypair`
- `save_keypair`
- `retrieve_keypair`
- `list_keypairs`
- `delete_keypair`

Enables:
- "Can you generate a ssh pair and copy it over to `host`?" --> Agent generates a ssh pair and saves it in vault, proceeds with task
- "Can you create dummy credentials for MSSQL and deploy it on docker?" --> Agent generate credentials in vault, references them as temporary files while deploying docker

Following system instructions is sufficient:
```
* **Credentials at vault:** use the credential helper tool to store new credentials and fetch existing ones when needed.
```

## Description

An MCP stdio server that brokers secure access to credentials stored in KeePassXC via the FreeDesktop.org Secret Service API. It exposes a minimal set of tools to list, search, create, update, delete, and securely retrieve secrets. Unlock requests always go through KeePassXC’s native approval prompts.

Why this exists: it lets local agents fetch secrets securely without copying them into env vars or logs. Secrets are never printed to stdout and plaintext retrieval is gated off by default. Primarily prevents my credentials leaking into LLM interactions and helps me set up secure development environments. Can potentially be used to rotate passwords in an agentic manner. I use it extensively and found value in it, so I decided to share.

## Quick Start
1) Prerequisites
- Python 3.10+
- KeePassXC with FreeDesktop Secret Service enabled
- `uv` for dependency and venv management

The server works across modern Linux desktops; ensure KeePassXC is the active Secret Service provider and that your session exposes the user D‑Bus (see the Codex CLI / D‑Bus section below).

2) Install
- Dev: `uv sync --extra dev`
- Runtime only: `uv sync`

3) Run (stdio MCP)
- `uv run -m keepassxc_dbus_mcp.mcp_server`
- or after install: `uv run keepassxc-dbus-mcp`

## KeePassXC Secret Service Settings
- Enable Secret Service: Settings → Secret Service → "Enable KeePassXC Freedesktop.org Secret Service integration".
- Authorization tab: enable all of the following for best safety when using agents:
- Show notification when passwords are retrieved by clients
- Confirm when passwords are retrieved by clients
- Confirm when clients request entry deletion
- Prompt to unlock database before searching
These settings ensure human-in-the-loop confirmations and visibility whenever an agent accesses or deletes secrets.


KeePassXC Secret Service recommended settings with exposed group

Hardening (suggested): you can expose only a specific group to the Secret Service rather than the entire database. Create a group (for example, "System Exposed") and select it under "Exposed database groups" in KeePassXC.


KeePassXC database group named 'System Exposed'

## Tools
Use these from your MCP client.

- `list_credentials()` → `[{ path, label, attributes }]`
- `get_credential_detail(credential_path)` → attributes dict or 404
- `search_credentials(q)` → contains-based list
- `create_credential({ label, password, username?, url?, notes?, attributes? })` → `{ path }`
- `update_credential({ credential_path, label?, password?, username?, url?, notes?, attributes? })`
- `delete_credential(credential_path)`
- `get_credential_secret_as_temp_file(credential_path, timeout=60)` → `{ temp_file_path }`
- `get_credential_secret(credential_path)` → gated by env variable

## SSH Keypairs
Two‑item aggregate linked by `KeypairID`.

- `create_keypair({ label, email, passphrase?, generate_passphrase?, algorithm='ed25519' })` → `{ keypair_id, private_path, meta_path, fingerprint, public_key_ssh }`
- `save_keypair({ keypair_id?, label, email, private_key_pem, public_key_ssh, passphrase?, algorithm })`
- `retrieve_keypair({ keypair_id? | credential_path?, include_passphrase?=false })` → `{ private_key_temp_file, passphrase_temp_file?, public_key_ssh, ... }`
- `list_keypairs()` → `[{ keypair_id, label, type, email, sha } ]`
- `delete_keypair(keypair_id)`

### Using passphrase‑protected private keys
- The `retrieve_keypair` tool returns temp file paths for both private key and passphrase (if any). You can use any SSH_ASKPASS program, or generate a tiny temp script that prints the passphrase from that file:
- Example: `ASKPASS=$(mktemp); printf '#!/usr/bin/env bash\ncat "$SSH_KEY_PASSPHRASE_FILE"\n' > "$ASKPASS"; chmod +x "$ASKPASS"`
- Then run: `SSH_ASKPASS_REQUIRE=force SSH_ASKPASS="$ASKPASS" SSH_KEY_PASSPHRASE_FILE=/path/to/pass.tmp ssh -i /path/to/priv.tmp user@host`
- Remove the temp script and files when done.

### SSH Keypair Storage Model
- Each SSH keypair is stored as an aggregate consisting of two Secret Service items linked by a shared `KeypairID`:
- Private item:
- Secret: the private key (OpenSSH PEM)
- Attributes: `Aggregate=ssh-keypair`, `Part=private`, `KeypairID=`, `Algorithm=ed25519`, `Fingerprint=SHA256:...`, `Email=` (also mirrored in `UserName`), `Title=`
- Meta item:
- Secret: the passphrase (empty if none)
- Attributes: `Aggregate=ssh-keypair`, `Part=meta`, `KeypairID=`, `Algorithm=ed25519`, `Fingerprint=SHA256:...`, `PublicKeyOpenSSH=`, `Email=`, `Title=`
- Rationale: secrets are cleanly separated (private key vs. passphrase), and both remain first-class Secret Service items that KeePassXC can manage (unlock prompts, approvals). We avoid stuffing binary material into attributes.
- What you’ll see in KeePassXC: two entries with the same title/username; one is the private part, the other is the meta part. They belong together. The server groups them using `KeypairID`.
- How to work with them:
- Discover: `list_keypairs()` shows `{ keypair_id, label, type, email, sha }` for quick selection.
- Use: `retrieve_keypair()` gives temp file paths for private key and (optionally) passphrase.
- Update: `save_keypair()` can create new or update an existing pair by `keypair_id` and keeps both entries in sync.
- Delete: remove both entries with the same `KeypairID` (call `delete_credential` for each path). A dedicated delete-keypair tool can be added if needed.

## Environment Variables
- `LOG_LEVEL`: Default `INFO`. Use `DEBUG` for troubleshooting (still stderr).
- `ALLOW_PLAINTEXT_SECRET`: Default `false`. Set to `true` only for trusted local use or tests.
- `PREFER_SHM`: Default `true`. When enabled, secrets are written to a temp file on `/dev/shm` (tmpfs) if available, minimizing disk persistence. If `/dev/shm` is not writable, the helper automatically falls back to the system temp directory.

## Codex CLI / D‑Bus Environment
- Errors: “No D‑Bus session bus” or “org.freedesktop.secrets not provided by any .service files”
- Why: the helper connects to KeePassXC through the FreeDesktop.org Secret Service on the user’s D‑Bus session bus. When sessions are launched by tools (e.g., Codex CLI, tmux, systemd units, SSH), `DBUS_SESSION_BUS_ADDRESS` and/or `XDG_RUNTIME_DIR` may be missing. In that case, `secretstorage` cannot reach the bus and you’ll see errors like “No D‑Bus session bus” or “org.freedesktop.secrets not provided by any .service files”.
- Fix: ensure your agent/CLI session inherits the user bus:
- `XDG_RUNTIME_DIR=/run/user/` (1000 on most single‑user desktops)
- `DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user//bus`
- KeePassXC must be running and providing Secret Service (see settings above).
- Codex example (`config.toml`):

```toml
[mcp_servers.credential-store]
command = "uv"
args = ["--directory", "/home/keepassxc-dbus-mcp", "run", "-m", "keepassxc_dbus_mcp.mcp_server"]
## Tip: echo $XDG_RUNTIME_DIR and $DBUS_SESSION_BUS_ADDRESS in your shell and
env = { XDG_RUNTIME_DIR = "/run/user/1000", DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/user/1000/bus"}
```

## Field Mapping Notes
- KeePassXC exposes default entry fields via Secret Service using exact, case‑sensitive keys: `Title`, `UserName`, `URL`, `Notes` (and `Password`, which is retrieved separately as the secret).
- Simplified model: typed fields (`label`, `username`, `url`, `notes`) populate canonical keys. The `attributes` bag is for custom keys only; reserved keys are ignored.
- Reserved keys: `Title`, `UserName`, `URL`, `Notes`, `Aggregate`, `Part`, `KeypairID`, `Algorithm`, `Fingerprint`, `Email`, `PublicKeyOpenSSH`.

## Screenshots (flow overview)

- Access request: database interactions trigger the KeePassXC prompt. You can choose not to remember and reset remembered decisions at any time.


KeePassXC access request prompt

- Search credentials: quick free‑text query showing attributes returned by `search_credentials`.


Example search for a demo credential and JSON attributes in the output

- Retrieve secret to a temp file: using `get_credential_secret_as_temp_file` — secrets never hit stdout; files auto‑delete after the timeout.


Tool call and success logs for get_credential_secret_as_temp_file

- Safe usage in function calls:


Codex CLI approval prompt for a command that reads a temp file and makes a local request

## Tested Environment
- OS: Ubuntu 24.04.3 LTS (Noble)
- Kernel: Linux 6.8.0-64-generic x86_64
- Desktop: GNOME Shell 46.0 (X11 session; `XDG_SESSION_TYPE=x11`)
- Secret Service provider: KeePassXC 2.7.10