@rui.branco/1password-mcp 0.1.1 → 0.1.3
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 +27 -16
- package/index.js +791 -620
- package/package.json +2 -2
- package/setup.js +93 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rui.branco/1password-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "1Password MCP server for Claude Code - list vaults and items, get secrets, generate passwords, manage items via service accounts. Multi-instance like jira-mcp.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"author": "Rui Branco",
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@1password/sdk": "^0.
|
|
27
|
+
"@1password/sdk": "^0.4.0",
|
|
28
28
|
"@modelcontextprotocol/sdk": "^1.25.3"
|
|
29
29
|
}
|
|
30
30
|
}
|
package/setup.js
CHANGED
|
@@ -28,19 +28,37 @@ function saveConfig(cfg) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// Non-interactive: setup add <name> <token> [description]
|
|
31
|
+
// setup add-desktop <name> <accountName> [description]
|
|
31
32
|
if (args[0] === "add" && args.length >= 3) {
|
|
32
33
|
const [, name, token, ...descArgs] = args;
|
|
33
34
|
const description = descArgs.join(" ").trim();
|
|
34
35
|
const config = loadConfig() || {};
|
|
35
36
|
if (!config.instances) config.instances = [];
|
|
36
37
|
const existing = config.instances.findIndex((i) => i.name === name);
|
|
37
|
-
const instance = { name, token };
|
|
38
|
+
const instance = { name, authType: "serviceAccount", token };
|
|
38
39
|
if (description) instance.description = description;
|
|
39
40
|
if (existing >= 0) config.instances[existing] = instance;
|
|
40
41
|
else config.instances.push(instance);
|
|
41
42
|
if (!config.defaultInstance) config.defaultInstance = name;
|
|
42
43
|
saveConfig(config);
|
|
43
|
-
console.log(`Instance "${name}" saved to ${configPath}`);
|
|
44
|
+
console.log(`Instance "${name}" saved to ${configPath} (serviceAccount)`);
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (args[0] === "add-desktop" && args.length >= 3) {
|
|
49
|
+
const [, name, accountName, ...descArgs] = args;
|
|
50
|
+
const description = descArgs.join(" ").trim();
|
|
51
|
+
const config = loadConfig() || {};
|
|
52
|
+
if (!config.instances) config.instances = [];
|
|
53
|
+
const existing = config.instances.findIndex((i) => i.name === name);
|
|
54
|
+
const instance = { name, authType: "desktop", accountName };
|
|
55
|
+
if (description) instance.description = description;
|
|
56
|
+
if (existing >= 0) config.instances[existing] = instance;
|
|
57
|
+
else config.instances.push(instance);
|
|
58
|
+
if (!config.defaultInstance) config.defaultInstance = name;
|
|
59
|
+
saveConfig(config);
|
|
60
|
+
console.log(`Instance "${name}" saved to ${configPath} (desktop: ${accountName})`);
|
|
61
|
+
console.log("Make sure the 1Password 8 desktop app is installed and the CLI integration is enabled (Settings → Developer → Connect with 1Password CLI).");
|
|
44
62
|
process.exit(0);
|
|
45
63
|
}
|
|
46
64
|
|
|
@@ -88,19 +106,86 @@ async function setup() {
|
|
|
88
106
|
}
|
|
89
107
|
}
|
|
90
108
|
|
|
91
|
-
console.log("
|
|
92
|
-
console.log("1.
|
|
93
|
-
console.log("2.
|
|
94
|
-
|
|
109
|
+
console.log("Pick auth mode:");
|
|
110
|
+
console.log(" 1. Desktop app (recommended for personal use — uses 1Password 8 biometric unlock, full vault access)");
|
|
111
|
+
console.log(" 2. Service account token (recommended for CI/shared — needs admin to provision, scoped vaults only)\n");
|
|
112
|
+
const mode = (await ask("Auth mode (1/2, default 1): ")).trim() || "1";
|
|
95
113
|
|
|
96
114
|
const name = (await ask("Instance name (e.g., work): ")).trim();
|
|
97
|
-
const token = (await ask("Service account token: ")).trim();
|
|
98
115
|
const description = (await ask("Description (optional): ")).trim();
|
|
99
116
|
|
|
100
117
|
const config = existing || { instances: [] };
|
|
101
118
|
if (!config.instances) config.instances = [];
|
|
102
119
|
const idx = config.instances.findIndex((i) => i.name === name);
|
|
103
|
-
|
|
120
|
+
let instance;
|
|
121
|
+
|
|
122
|
+
if (mode === "2") {
|
|
123
|
+
console.log("\nCreate a service account token at:");
|
|
124
|
+
console.log(" https://start.1password.com/developer-tools/infrastructure-secrets/serviceaccount");
|
|
125
|
+
const token = (await ask("Service account token (ops_...): ")).trim();
|
|
126
|
+
instance = { name, authType: "serviceAccount", token };
|
|
127
|
+
} else {
|
|
128
|
+
console.log("\n=== One-time 1Password 8 setup (required for desktop auth) ===");
|
|
129
|
+
console.log("");
|
|
130
|
+
console.log("Open the 1Password 8 desktop app (not the browser — the Mac/Windows app).");
|
|
131
|
+
console.log("");
|
|
132
|
+
console.log(" 1. Open Settings (cmd+, on Mac / ctrl+, on Windows)");
|
|
133
|
+
console.log(" 2. Click the 'Developer' tab on the left");
|
|
134
|
+
console.log(" 3. Tick 'Integrate with 1Password CLI'");
|
|
135
|
+
console.log(" (under 'Command-Line Interface (CLI)')");
|
|
136
|
+
console.log(" 4. Tick 'Integrate with other apps'");
|
|
137
|
+
console.log(" (under 'Integrate with the 1Password SDKs')");
|
|
138
|
+
console.log(" ** THIS IS THE KEY ONE — without it the SDK can't unlock. **");
|
|
139
|
+
console.log(" 5. (Optional) Settings → Security → 'Unlock using Touch ID'");
|
|
140
|
+
console.log("");
|
|
141
|
+
console.log("The first time the MCP calls 1Password you'll get a system prompt");
|
|
142
|
+
console.log("asking to authorize '1password-mcp' — click Approve.");
|
|
143
|
+
console.log("");
|
|
144
|
+
console.log("=== Finding your account name ===");
|
|
145
|
+
console.log("");
|
|
146
|
+
console.log("Open 1Password 8 → click the account switcher in the top-left.");
|
|
147
|
+
console.log("The signin address shown next to your name is what you want here,");
|
|
148
|
+
console.log("e.g. 'my.1password.com' or 'my-team.1password.com'.");
|
|
149
|
+
console.log("");
|
|
150
|
+
const accountName = (await ask("Account name (e.g., my.1password.com): ")).trim();
|
|
151
|
+
if (!accountName) {
|
|
152
|
+
console.error("Account name is required. Aborting.");
|
|
153
|
+
rl.close();
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
instance = { name, authType: "desktop", accountName };
|
|
157
|
+
|
|
158
|
+
// Validate by actually trying to talk to the desktop app. This will pop the
|
|
159
|
+
// OS-level authorization prompt on first use.
|
|
160
|
+
console.log("\nValidating with 1Password desktop app (you may get an auth prompt)…");
|
|
161
|
+
try {
|
|
162
|
+
const sdk = require("@1password/sdk");
|
|
163
|
+
const client = await sdk.createClient({
|
|
164
|
+
auth: new sdk.DesktopAuth(accountName),
|
|
165
|
+
integrationName: "1password-mcp-setup",
|
|
166
|
+
integrationVersion: "v1",
|
|
167
|
+
});
|
|
168
|
+
const probe = [];
|
|
169
|
+
for await (const v of await client.vaults.list()) {
|
|
170
|
+
probe.push(v);
|
|
171
|
+
if (probe.length >= 1) break;
|
|
172
|
+
}
|
|
173
|
+
console.log(`Validated. Saw vault: ${probe[0]?.title || "(none visible)"}.`);
|
|
174
|
+
} catch (e) {
|
|
175
|
+
console.error("");
|
|
176
|
+
console.error("Validation failed: " + e.message);
|
|
177
|
+
console.error("");
|
|
178
|
+
console.error("Common causes:");
|
|
179
|
+
console.error(" - 'Integrate with other apps' is NOT ticked in 1Password Settings → Developer");
|
|
180
|
+
console.error(" - 1Password 8 desktop app is not running or locked");
|
|
181
|
+
console.error(" - Account name is wrong (check the account switcher in 1Password 8)");
|
|
182
|
+
console.error("");
|
|
183
|
+
console.error("Fix the issue and re-run this setup.");
|
|
184
|
+
rl.close();
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
104
189
|
if (description) instance.description = description;
|
|
105
190
|
if (idx >= 0) config.instances[idx] = instance;
|
|
106
191
|
else config.instances.push(instance);
|