# vaultgate

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/adamrowles1996/vaultgate  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/vaultgate

## Description
Self-hosted remote MCP server for Bitwarden and Vaultwarden with OAuth 2.1; agents hold tokens only

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `npx` (confidence: low):

```json
"mcpServers": {
  "vaultgate": {
    "command": "npx",
    "args": ["-y","vaultgate"]
  }
}
```

## Documentation & README

# vaultgate

[![CI](https://github.com/adamrowles1996/vaultgate/actions/workflows/ci.yml/badge.svg)](https://github.com/adamrowles1996/vaultgate/actions/workflows/ci.yml)
[![CodeQL](https://github.com/adamrowles1996/vaultgate/actions/workflows/codeql.yml/badge.svg)](https://github.com/adamrowles1996/vaultgate/actions/workflows/codeql.yml)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/adamrowles1996/vaultgate/badge)](https://scorecard.dev/viewer/?uri=github.com/adamrowles1996/vaultgate)
[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)

A self-hosted, remote [MCP](https://modelcontextprotocol.io) server that lets hosted AI agents
such as Claude, Claude Cowork, Claude Code and Codex **use your credentials without ever seeing
them**. The credentials stay in your [Bitwarden](https://bitwarden.com) (or Vaultwarden) vault.
vaultgate uses them on the agent's behalf against systems you define (an HTTP API, Microsoft
Graph, a SQL Server or PostgreSQL database, an SSH or WinRM host, a GitHub repository searched
with Semble) under your policy, and hands back only the result. It is its own OAuth 2.1 authorization server, so the agent holds a
short-lived, scoped, revocable token and nothing else.

> **Status: release candidate.** Milestones M1 to M7 are merged: configuration, SQLite store,
> operator identity with TOTP, the OAuth 2.1 authorization server, the MCP tool surface, the
> managed `bw serve` backend, the audit trail, packaging and the Azure template. M8 (hardening and
> compatibility evidence) is in progress. The actions layer, opt-in and off by default, has landed
> through M14: M9 the engine, the operator pages and the `http` connector, M10 the Microsoft Graph
> credential adapter, M11 `sql`, M12 `ssh`, M13 `winrm`, and M14 the policy-form validation
> messages, the call-history and unexpected-write views, grant management from the
> connected-clients list and the elicitation hardening. M16 adds the `code` connector: Semble code
> search over private GitHub repositories, with its sidecar ([guide](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/guides/code-search.md)).
> `browser` is M15; see [`docs/PLAN.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/PLAN.md).

## Why

**A credential an agent can read ends up in the transcript.** Once an agent reveals a password
in order to use it, the value sits in the model's context, in the chat transcript, in the client's
logs and on whatever command line the agent builds, and revoking the agent does not take it back.
vaultgate is built so that the agent never needs the value:

- **Use, don't read.** With the actions layer enabled
  ([guide](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/guides/actions.md), [spec 13](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/spec/13-actions.md) and
  [13a](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/spec/13a-actions-operations.md), [ADR 0007](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/adr/0007-typed-actions-with-operator-policy.md)),
  an agent names a target you defined and describes an operation: an HTTP request, a SQL query
  or statement, a command on an SSH or WinRM host, a Semble search of a GitHub repository.
  vaultgate fetches the credential from the
  vault, connects to the pinned destination, runs the operation inside your policy, scrubs every
  injected value from the result and returns what is left. An agent never supplies a host, a URL
  base, a database name or a credential; its arguments change what runs, never where or as whom.
- **Writes are opt-in three times.** A write needs its own scope at consent, a target policy that
  allows it and, when you ask for it, a human confirmation on every call; the console lists
  every write that ran without one.
- **One audited door for the rare value that must be read.** The vault tools return metadata. A
  single tool returns a secret value, one field of one item per call, behind its own scope, with
  every call audited.
- **Nothing runs on the vaultgate host.** No tool runs whatever an agent sends wherever it likes: `ssh_run` and
  `winrm_run` run one command on one configured host under your allowlist (a target that accepts
  any command needs both its own flag and the deployment's consent), and every operation executes
  at its target.
- **The agent holds a token and nothing else.** The master password and API key live only in the
  vaultgate process on your host, encrypted under your secret key once you connect the vault on
  the console's Vault page.
- **Standards as written.** OAuth 2.1, PKCE, RFC 9728 / 8414 / 8707 / 7591 /
  7009 / 9207 and Client ID Metadata Documents, per the MCP authorization
  specification (2026-07-28).
- **Any Bitwarden.** bitwarden.com, bitwarden.eu, self-hosted Bitwarden and Vaultwarden.
- **Boring to operate.** One process, one SQLite file, structured logs, health
  probes, an audit trail. `docker compose up` is a complete installation.

### Compared with other Bitwarden MCP servers

Hosted agents reach MCP servers over HTTPS and cannot run a process next to your vault, and the
other Bitwarden MCP servers are built for exactly that local process:

| Server                                                                                                                                                                         | Where it runs                                                  | Who holds the master password / API key                                                                        | Client authorization                                                                                                                               | Consent and scopes                                                                                                                                     | Revocation                                                                                                    | Audit trail                                                                      | Using a credential without seeing it                                                                       |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| [Official `bitwarden/mcp-server`](https://github.com/bitwarden/mcp-server)                                                                                                     | Local, stdio; its README says it must never be hosted publicly | Your machine: the `bw` CLI session (`BW_SESSION`) in the client's configuration, or an OS password dialog      | None; whoever launches the process                                                                                                                 | None; every tool is available to the launching client                                                                                                  | Lock the vault or end the `bw` session                                                                        | Not described                                                                    | Not described                                                                                              |
| [warden-mcp](https://github.com/icoretech/warden-mcp), remote mode                                                                                                             | A long-running HTTP service you host                           | The client, which sends them as `X-BW-Password`, `X-BW-ClientId` and `X-BW-ClientSecret` headers on every call | None built in ("no built-in authentication layer in v1")                                                                                           | None; `READONLY` and `NOREVEAL` switches apply to every client alike                                                                                   | Rotate the Bitwarden credentials                                                                              | Not described                                                                    | Not described                                                                                              |
| Typical community servers, e.g. [vaultwarden-mcp](https://github.com/rmangaha/vaultwarden-mcp), [bitwarden-mcp-server](https://github.com/giuliolibrando/bitwarden-mcp-server) | Local stdio, or a plain HTTP port                              | The server process, from environment variables holding the e-mail address and master password                  | None                                                                                                                                               | None                                                                                                                                                   | Rotate the Bitwarden credentials                                                                              | Not described                                                                    | Not described                                                                                              |
| vaultgate                                                                                                                                                                      | Your host, reachable over HTTPS by hosted agents               | The vaultgate process only; the agent holds an opaque token                                                    | Built-in OAuth 2.1 authorization server: operator login with TOTP, PKCE, RFC 9728 / 8414 / 8707 / 7591 / 7009 / 9207, Client ID Metadata Documents | Per-client consent page; `vault:read`, `vault:reveal`, `vault:generate`, `vault:write` (off by default); `actions:*` scopes for each enabled connector | Per client or per token from the console's Agents page; refresh tokens rotate and a replay revokes the family | Every tool call, login, consent, token issue, refresh and revocation, exportable | Typed actions at targets you define: `http` (with Microsoft Graph), `sql`, `ssh`, `winrm`, `code` (Semble) |

"Not described" means the project's README does not document one. Dated verification notes with
links, and when the official stdio server is the better choice: [`docs/comparison.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/comparison.md).

## Quick start

The current version is 0.1.0-rc.22 (`package.json`; releases are tagged on GitHub). On a VM with
Docker Engine, the Compose plugin, a DNS name pointing at it and ports 80 and 443 reachable from
the internet:

```bash
git clone https://github.com/adamrowles1996/vaultgate.git
cd vaultgate
cp .env.example .env
```

Set `VAULTGATE_DOMAIN`, `VAULTGATE_PUBLIC_URL` and `VAULTGATE_VERSION` in `.env`, then:

```bash
mkdir -p secrets
head -c 32 /dev/urandom | base64 > secrets/vaultgate_secret_key
touch secrets/bw_password secrets/bw_client_secret
chmod 0400 secrets/* && sudo chown 10001 secrets/*
docker compose up -d
docker compose logs -f vaultgate
```

First run: the log prints a one-time `/setup?token=…` URL. Open it and create the operator
account with an e-mail address, a password and a code from your authenticator (TOTP). That
password is vaultgate's own operator login; it is not, and never becomes, your Bitwarden master
password. Sign in, and on the **Vault** page connect the vault: server, API key client id and
secret, and master password. vaultgate stores that connection encrypted under
`VAULTGATE_SECRET_KEY`, so it survives restarts and upgrades. Then add `https://<host>/mcp` to
Claude (or Claude Code, Codex, the MCP Inspector) as a remote MCP server and approve the scopes on
the consent page. The `bw` CLI that vaultgate drives is bundled in the image and installed by
`install.sh`; nothing else is needed on the host. Walkthrough:
[`docs/guides/first-run.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/guides/first-run.md); details and the verification of the
image: [`docs/guides/install-docker-compose.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/guides/install-docker-compose.md).

To let agents use credentials rather than read them, set `VAULTGATE_ENABLE_ACTIONS=true` and the
switch for each connector you want, restart, and add connections (targets) on the console's **Connections**
page: [`docs/guides/actions.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/guides/actions.md).

## How it works

```text
Claude / Codex ──HTTPS + Bearer──▶ vaultgate ──loopback──▶ bw serve ──▶ Bitwarden
                 ▲                    │    │
                 │                    │    └──pinned──▶ your API, database, SSH or WinRM host
                 └── OAuth 2.1 ◀──────┘        (credential injected by vaultgate, result scrubbed)
                   (consent page, operator login with TOTP)
```

1. An agent calls `/mcp` and is challenged with `WWW-Authenticate`.
2. It discovers the authorization server from the protected resource metadata,
   registers (Client ID Metadata Document, dynamic registration, or a
   pre-registered id) and sends you to the consent page.
3. You log in (password + TOTP) and approve the scopes: `vault:read`,
   `vault:reveal`, `vault:generate`, optionally `vault:write`, and the `actions:*`
   scopes of each connector the deployment enables.
4. With an `actions:*` scope, the agent lists the targets granted to it and calls
   them: `http_request`, `sql_query`, `sql_execute`, `ssh_run`, `winrm_run`, and
   `code_search`, `code_find_related` and `code_read` for Semble connections.
   vaultgate fetches the credential from the vault, performs the operation at the
   target and returns the scrubbed result; the credential never reaches the agent.
5. With the vault scopes, it can search items, read metadata, reveal one secret
   field at a time, generate passwords and, if allowed, create or update items.

## Install

TLS is always terminated in front of vaultgate; every method below ends with a
public `https://` origin that hosted agents can reach.

| Method                                  | Guide                                                                            |
| --------------------------------------- | -------------------------------------------------------------------------------- |
| Docker Compose with Caddy (recommended) | [`docs/guides/install-docker-compose.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/guides/install-docker-compose.md) |
| Debian or Ubuntu VM, `install.sh`       | [`docs/guides/install-linux.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/guides/install-linux.md)                   |
| Your own reverse proxy (Caddy, nginx)   | [`docs/guides/reverse-proxy.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/guides/reverse-proxy.md)                   |

Releases publish `ghcr.io/adamrowles1996/vaultgate:<version>` for `linux/amd64` and
`linux/arm64`, signed with Sigstore cosign and carrying an SBOM and a provenance attestation,
plus `vaultgate-<version>.tgz` and its `.sha256` for the script install.

## Documentation

| Document                                       | What it is                                                                                                                                                       |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`docs/guides/`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/guides/README.md)        | User guides: first run, connecting Claude, Claude Code, Codex and the Inspector, tools and scopes, self-hosted Bitwarden, backup, upgrading, security model, FAQ |
| [`docs/spec/`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/spec/README.md)            | The normative specification, one file per concern                                                                                                                |
| [`docs/PLAN.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/PLAN.md)                 | Milestones, exit criteria, risks                                                                                                                                 |
| [`docs/THREAT_MODEL.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/THREAT_MODEL.md) | Assets, attackers, mitigations, residual risks                                                                                                                   |
| [`docs/comparison.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/comparison.md)     | How vaultgate differs from the other Bitwarden MCP servers, with dated verification notes                                                                        |
| [`docs/adoption.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/adoption.md)         | Listings, channels and app-store definitions, with the submission mechanics for each                                                                             |
| [`server.json`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/server.json)                   | The MCP Registry listing; how to publish it: [`docs/guides/publishing.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/guides/publishing.md)                                                            |
| [`docs/adr/`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/docs/adr/README.md)              | Architecture decision records                                                                                                                                    |
| [`CONTRIBUTING.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/CONTRIBUTING.md)           | Development workflow and quality gates                                                                                                                           |
| [`SECURITY.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/SECURITY.md)                   | Reporting vulnerabilities                                                                                                                                        |

## Development

Requires Node 26 (see `.nvmrc`) and [mise](https://mise.jdx.dev) for the pinned external
linters.

```bash
mise install         # actionlint, shellcheck, shfmt, hadolint, gitleaks, editorconfig-checker
npm ci
npm run dev          # runs src/main.ts directly with Node's type stripping
npm run quality      # format, every linter, types, dead code, file sizes, provenance, tests at 100%
```

Every check that runs in CI runs locally with `npm run quality`. See
[`CONTRIBUTING.md`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/CONTRIBUTING.md) for the rules the repository enforces and why.

## Licence

Apache-2.0. See [`LICENSE`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/LICENSE) and [`NOTICE`](https://github.com/adamrowles1996/vaultgate/blob/HEAD/NOTICE).

