@icoretech/warden-mcp 0.1.10 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,9 +56,15 @@ npm install -g @bitwarden/cli
56
56
  Or run with an explicit binary path:
57
57
 
58
58
  ```bash
59
- BW_BIN=/absolute/path/to/bw npx -y @icoretech/warden-mcp
59
+ BW_BIN=/absolute/path/to/bw npx -y @icoretech/warden-mcp@latest
60
60
  ```
61
61
 
62
+ `warden-mcp` intentionally bundles a vetted `@bitwarden/cli` version instead of
63
+ blindly following the newest upstream CLI on every release. New `bw` releases
64
+ can change login and unlock behavior in ways that break automation, so `bw`
65
+ upgrades should be smoke-tested against real Vaultwarden and Bitwarden flows
66
+ before bumping the bundled version.
67
+
62
68
  ## Install And Run
63
69
 
64
70
  ### Choose a transport
@@ -69,7 +75,7 @@ BW_BIN=/absolute/path/to/bw npx -y @icoretech/warden-mcp
69
75
  ### Local stdio mode
70
76
 
71
77
  ```bash
72
- npx -y @icoretech/warden-mcp --stdio
78
+ npx -y @icoretech/warden-mcp@latest --stdio
73
79
  ```
74
80
 
75
81
  For stdio mode, you must provide Bitwarden credentials up front via env vars:
@@ -78,7 +84,7 @@ For stdio mode, you must provide Bitwarden credentials up front via env vars:
78
84
  BW_HOST=https://vaultwarden.example.com \
79
85
  BW_USER=user@example.com \
80
86
  BW_PASSWORD='your-master-password' \
81
- npx -y @icoretech/warden-mcp --stdio
87
+ npx -y @icoretech/warden-mcp@latest --stdio
82
88
  ```
83
89
 
84
90
  API key login works too:
@@ -88,7 +94,7 @@ BW_HOST=https://vaultwarden.example.com \
88
94
  BW_CLIENTID=user.xxxxx \
89
95
  BW_CLIENTSECRET=xxxxx \
90
96
  BW_PASSWORD='your-master-password' \
91
- npx -y @icoretech/warden-mcp --stdio
97
+ npx -y @icoretech/warden-mcp@latest --stdio
92
98
  ```
93
99
 
94
100
  ### Shared HTTP mode
@@ -96,7 +102,7 @@ npx -y @icoretech/warden-mcp --stdio
96
102
  Start one long-lived MCP server:
97
103
 
98
104
  ```bash
99
- npx -y @icoretech/warden-mcp
105
+ npx -y @icoretech/warden-mcp@latest
100
106
  ```
101
107
 
102
108
  Verify it is up:
@@ -115,13 +121,13 @@ This mode is what makes `warden-mcp` different from a simple local wrapper:
115
121
  ### Docker
116
122
 
117
123
  ```bash
118
- docker run --rm -p 3005:3005 ghcr.io/icoretech/warden-mcp
124
+ docker run --rm -p 3005:3005 ghcr.io/icoretech/warden-mcp:latest
119
125
  ```
120
126
 
121
127
  ### Global install
122
128
 
123
129
  ```bash
124
- npm install -g @icoretech/warden-mcp
130
+ npm install -g @icoretech/warden-mcp@latest
125
131
  warden-mcp
126
132
  ```
127
133
 
@@ -130,7 +136,7 @@ warden-mcp
130
136
  For local MCP hosts, stdio is the most portable option.
131
137
 
132
138
  ```bash
133
- npx -y @icoretech/warden-mcp --stdio
139
+ npx -y @icoretech/warden-mcp@latest --stdio
134
140
  ```
135
141
 
136
142
  The examples below use Bitwarden API-key auth. If you prefer username/password login, replace `BW_CLIENTID` + `BW_CLIENTSECRET` with `BW_USER`.
@@ -146,10 +152,10 @@ codex mcp add warden \
146
152
  --env BW_CLIENTID=user.xxxxx \
147
153
  --env BW_CLIENTSECRET=xxxxx \
148
154
  --env BW_PASSWORD='your-master-password' \
149
- -- npx -y @icoretech/warden-mcp --stdio
155
+ -- npx -y @icoretech/warden-mcp@latest --stdio
150
156
 
151
157
  # Claude Code
152
- claude mcp add-json warden '{"command":"npx","args":["-y","@icoretech/warden-mcp","--stdio"],"env":{"BW_HOST":"https://vaultwarden.example.com","BW_CLIENTID":"user.xxxxx","BW_CLIENTSECRET":"xxxxx","BW_PASSWORD":"your-master-password"}}'
158
+ claude mcp add-json warden '{"command":"npx","args":["-y","@icoretech/warden-mcp@latest","--stdio"],"env":{"BW_HOST":"https://vaultwarden.example.com","BW_CLIENTID":"user.xxxxx","BW_CLIENTSECRET":"xxxxx","BW_PASSWORD":"your-master-password"}}'
153
159
 
154
160
  # Qwen Code
155
161
  qwen mcp add warden \
@@ -157,7 +163,7 @@ qwen mcp add warden \
157
163
  -e BW_CLIENTID=user.xxxxx \
158
164
  -e BW_CLIENTSECRET=xxxxx \
159
165
  -e BW_PASSWORD=your-master-password \
160
- npx -y @icoretech/warden-mcp --stdio
166
+ npx -y @icoretech/warden-mcp@latest --stdio
161
167
  ```
162
168
 
163
169
  ### JSON config hosts
@@ -176,7 +182,7 @@ Shared JSON shape:
176
182
  "mcpServers": {
177
183
  "warden": {
178
184
  "command": "npx",
179
- "args": ["-y", "@icoretech/warden-mcp", "--stdio"],
185
+ "args": ["-y", "@icoretech/warden-mcp@latest", "--stdio"],
180
186
  "env": {
181
187
  "BW_HOST": "https://vaultwarden.example.com",
182
188
  "BW_CLIENTID": "user.xxxxx",
@@ -193,7 +199,8 @@ Codex uses TOML instead of JSON:
193
199
  ```toml
194
200
  [mcp_servers.warden]
195
201
  command = "npx"
196
- args = ["-y", "@icoretech/warden-mcp", "--stdio"]
202
+ args = ["-y", "@icoretech/warden-mcp@latest", "--stdio"]
203
+ startup_timeout_sec = 30
197
204
 
198
205
  [mcp_servers.warden.env]
199
206
  BW_HOST = "https://vaultwarden.example.com"
@@ -202,6 +209,10 @@ BW_CLIENTSECRET = "xxxxx"
202
209
  BW_PASSWORD = "your-master-password"
203
210
  ```
204
211
 
212
+ `startup_timeout_sec = 30` is a practical Codex default when using `npx`,
213
+ because a cold first launch can spend several seconds downloading and unpacking
214
+ the package before MCP initialization begins.
215
+
205
216
  ### Windsurf
206
217
 
207
218
  Windsurf uses the same stdio idea but stores it in `~/.codeium/windsurf/mcp_config.json`:
@@ -211,7 +222,7 @@ Windsurf uses the same stdio idea but stores it in `~/.codeium/windsurf/mcp_conf
211
222
  "mcpServers": {
212
223
  "warden": {
213
224
  "command": "npx",
214
- "args": ["-y", "@icoretech/warden-mcp", "--stdio"],
225
+ "args": ["-y", "@icoretech/warden-mcp@latest", "--stdio"],
215
226
  "env": {
216
227
  "BW_HOST": "https://vaultwarden.example.com",
217
228
  "BW_CLIENTID": "user.xxxxx",
@@ -230,7 +241,7 @@ If your MCP host supports Streamable HTTP with custom headers, you can connect t
230
241
  Start the shared server:
231
242
 
232
243
  ```bash
233
- npx -y @icoretech/warden-mcp
244
+ npx -y @icoretech/warden-mcp@latest
234
245
  ```
235
246
 
236
247
  Every MCP request must include:
@@ -419,7 +430,7 @@ If you run `warden-mcp` beyond local development, review these items:
419
430
  Run the published package in HTTP mode and verify the server is up:
420
431
 
421
432
  ```bash
422
- npx -y @icoretech/warden-mcp
433
+ npx -y @icoretech/warden-mcp@latest
423
434
  curl -fsS http://localhost:3005/healthz
424
435
  ```
425
436
 
package/bin/warden-mcp.js CHANGED
@@ -3,9 +3,9 @@
3
3
  // bin/warden-mcp.js — CLI entry for @icoretech/warden-mcp
4
4
 
5
5
  import { spawnSync } from 'node:child_process';
6
- import { accessSync, constants, existsSync } from 'node:fs';
6
+ import { accessSync, constants, existsSync, readFileSync } from 'node:fs';
7
7
  import { createRequire } from 'node:module';
8
- import { dirname, join, resolve } from 'node:path';
8
+ import { dirname, resolve } from 'node:path';
9
9
  import { fileURLToPath } from 'node:url';
10
10
 
11
11
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -14,12 +14,12 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
14
14
  if (!process.env.BW_BIN) {
15
15
  try {
16
16
  const require = createRequire(import.meta.url);
17
- // @bitwarden/cli installs the binary at <pkg>/dist/bw (the npm bin shim
18
- // lives at node_modules/.bin/bw, but we resolve to the actual package).
17
+ const { resolveBundledBwCandidate } = await import(
18
+ resolve(__dirname, '../dist/bw/resolveBwBin.js')
19
+ );
19
20
  const pkgManifest = require.resolve('@bitwarden/cli/package.json');
20
- const pkgDir = dirname(pkgManifest);
21
- // The CLI binary is published as `bw` (no extension) inside the package.
22
- const candidate = join(pkgDir, 'dist', 'bw');
21
+ const pkgJson = JSON.parse(readFileSync(pkgManifest, 'utf8'));
22
+ const candidate = resolveBundledBwCandidate(pkgManifest, pkgJson.bin);
23
23
  if (existsSync(candidate)) {
24
24
  try {
25
25
  accessSync(candidate, constants.X_OK);
@@ -0,0 +1,10 @@
1
+ import { dirname, join } from 'node:path';
2
+ export function resolveBundledBwCandidate(pkgManifestPath, pkgBin) {
3
+ const pkgDir = dirname(pkgManifestPath);
4
+ const binEntry = typeof pkgBin === 'string'
5
+ ? pkgBin
6
+ : typeof pkgBin?.bw === 'string'
7
+ ? pkgBin.bw
8
+ : 'dist/bw';
9
+ return join(pkgDir, binEntry);
10
+ }
package/dist/server.js CHANGED
@@ -16,7 +16,11 @@ if (useStdio) {
16
16
  else {
17
17
  const PORT = Number.parseInt(process.env.PORT ?? '3005', 10);
18
18
  const app = createKeychainApp();
19
- app.listen(PORT, () => {
19
+ const server = app.listen(PORT, () => {
20
20
  console.log(`[warden-mcp] listening on http://localhost:${PORT}/sse`);
21
21
  });
22
+ await new Promise((resolve, reject) => {
23
+ server.once('close', resolve);
24
+ server.once('error', reject);
25
+ });
22
26
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@icoretech/warden-mcp",
4
- "version": "0.1.10",
4
+ "version": "0.1.13",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "description": "Vaultwarden/Bitwarden MCP server backed by Bitwarden CLI (bw).",
@@ -48,7 +48,7 @@
48
48
  "zod": "^4.3.6"
49
49
  },
50
50
  "optionalDependencies": {
51
- "@bitwarden/cli": "2026.2.0"
51
+ "@bitwarden/cli": "2026.1.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@biomejs/biome": "^2.4.8",