@rui.branco/1password-mcp 0.1.4 → 0.1.5
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/index.js +113 -36
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -522,22 +522,22 @@ const TOOL_DEFINITIONS = [
|
|
|
522
522
|
{
|
|
523
523
|
name: "op_update_item",
|
|
524
524
|
description:
|
|
525
|
-
"Update an existing item
|
|
525
|
+
"Update any part of an existing item — title, category, fields, tags, websites, sections, or notes. Omitted parameters are preserved. Fields are patched by title (existing fields match case-insensitively; new fields require `type`). Tags, websites, and sections are REPLACED when passed.",
|
|
526
526
|
inputSchema: {
|
|
527
527
|
type: "object",
|
|
528
528
|
properties: {
|
|
529
529
|
vault: { type: "string", description: "Vault id or title." },
|
|
530
530
|
item: { type: "string", description: "Item id or title to update." },
|
|
531
531
|
title: { type: "string", description: "New title (optional)." },
|
|
532
|
-
|
|
533
|
-
type: "
|
|
534
|
-
|
|
535
|
-
|
|
532
|
+
category: {
|
|
533
|
+
type: "string",
|
|
534
|
+
description:
|
|
535
|
+
"New category (rare). One of Login, SecureNote, Password, ApiCredentials, Database, Server, Email, Identity, CreditCard, etc.",
|
|
536
536
|
},
|
|
537
537
|
fields: {
|
|
538
538
|
type: "array",
|
|
539
539
|
description:
|
|
540
|
-
"Field patches: [{title, value, type?, sectionId?}]. Existing fields
|
|
540
|
+
"Field patches: [{title, value, type?, sectionId?}]. Existing fields matched by title have their values replaced. New fields require `type` (Text | Concealed | Totp | Email | Url | Phone).",
|
|
541
541
|
items: {
|
|
542
542
|
type: "object",
|
|
543
543
|
properties: {
|
|
@@ -549,6 +549,46 @@ const TOOL_DEFINITIONS = [
|
|
|
549
549
|
required: ["title", "value"],
|
|
550
550
|
},
|
|
551
551
|
},
|
|
552
|
+
tags: {
|
|
553
|
+
type: "array",
|
|
554
|
+
items: { type: "string" },
|
|
555
|
+
description:
|
|
556
|
+
"Replace the tag list. Omit to preserve existing tags; pass [] to clear.",
|
|
557
|
+
},
|
|
558
|
+
websites: {
|
|
559
|
+
type: "array",
|
|
560
|
+
description:
|
|
561
|
+
"Replace the website list. Each website is {url, label?, autofillBehavior?}. Omit to preserve existing websites.",
|
|
562
|
+
items: {
|
|
563
|
+
type: "object",
|
|
564
|
+
properties: {
|
|
565
|
+
url: { type: "string" },
|
|
566
|
+
label: { type: "string" },
|
|
567
|
+
autofillBehavior: {
|
|
568
|
+
type: "string",
|
|
569
|
+
description: "'AnywhereOnWebsite' (default) or 'Never'.",
|
|
570
|
+
},
|
|
571
|
+
},
|
|
572
|
+
required: ["url"],
|
|
573
|
+
},
|
|
574
|
+
},
|
|
575
|
+
sections: {
|
|
576
|
+
type: "array",
|
|
577
|
+
description: "Replace the section list. Each section is {title, id?}.",
|
|
578
|
+
items: {
|
|
579
|
+
type: "object",
|
|
580
|
+
properties: {
|
|
581
|
+
title: { type: "string" },
|
|
582
|
+
id: { type: "string" },
|
|
583
|
+
},
|
|
584
|
+
required: ["title"],
|
|
585
|
+
},
|
|
586
|
+
},
|
|
587
|
+
notes: {
|
|
588
|
+
type: "string",
|
|
589
|
+
description:
|
|
590
|
+
"Replace the notesPlain field. Omit to preserve existing notes.",
|
|
591
|
+
},
|
|
552
592
|
instance: {
|
|
553
593
|
type: "string",
|
|
554
594
|
description: "Instance name. Uses default if omitted.",
|
|
@@ -952,44 +992,81 @@ async function updateItemHandler(args) {
|
|
|
952
992
|
const current = await client.items.get(vault.id, itemRef.id);
|
|
953
993
|
const updated = { ...current };
|
|
954
994
|
|
|
995
|
+
// --- title (rename) ---
|
|
955
996
|
if (args.title) updated.title = args.title;
|
|
997
|
+
|
|
998
|
+
// --- category (rarely changed, but the SDK allows it) ---
|
|
999
|
+
if (args.category) {
|
|
1000
|
+
const cat = sdk.ItemCategory[args.category];
|
|
1001
|
+
if (!cat) throw new Error(`Unknown category "${args.category}".`);
|
|
1002
|
+
updated.category = cat;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
// --- tags (replace when passed; preserved when omitted) ---
|
|
956
1006
|
if (args.tags) updated.tags = args.tags;
|
|
957
1007
|
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1008
|
+
// --- websites (replace when passed; preserved when omitted) ---
|
|
1009
|
+
if (Array.isArray(args.websites)) {
|
|
1010
|
+
updated.websites = args.websites.map((w) => ({
|
|
1011
|
+
url: w.url,
|
|
1012
|
+
label: w.label || "website",
|
|
1013
|
+
autofillBehavior:
|
|
1014
|
+
w.autofillBehavior === "Never"
|
|
1015
|
+
? sdk.AutofillBehavior.Never
|
|
1016
|
+
: sdk.AutofillBehavior.AnywhereOnWebsite,
|
|
1017
|
+
}));
|
|
1018
|
+
}
|
|
963
1019
|
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
1020
|
+
// --- sections (replace when passed; preserved when omitted) ---
|
|
1021
|
+
if (Array.isArray(args.sections)) {
|
|
1022
|
+
updated.sections = args.sections.map((s) => ({
|
|
1023
|
+
id: s.id || s.title.toLowerCase().replace(/\s+/g, "_"),
|
|
1024
|
+
title: s.title,
|
|
1025
|
+
}));
|
|
1026
|
+
}
|
|
971
1027
|
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1028
|
+
// --- fields (patch by title, add new ones with explicit type) ---
|
|
1029
|
+
const nextFields = [...(current.fields || [])];
|
|
1030
|
+
const fieldIndexByTitle = new Map(
|
|
1031
|
+
nextFields.map((f, idx) => [(f.title || "").toLowerCase(), idx]),
|
|
1032
|
+
);
|
|
1033
|
+
|
|
1034
|
+
function upsertField({ title, value, type, sectionId }) {
|
|
1035
|
+
const key = title.toLowerCase();
|
|
1036
|
+
const existingIdx = fieldIndexByTitle.get(key);
|
|
1037
|
+
if (existingIdx !== undefined) {
|
|
1038
|
+
nextFields[existingIdx] = { ...nextFields[existingIdx], value };
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
if (!type) {
|
|
1042
|
+
throw new Error(
|
|
1043
|
+
`Field "${title}" doesn't exist on the item — pass a 'type' to add it as a new field.`,
|
|
1044
|
+
);
|
|
989
1045
|
}
|
|
990
|
-
|
|
1046
|
+
const ft = sdk.ItemFieldType[type];
|
|
1047
|
+
if (!ft) throw new Error(`Unknown field type "${type}".`);
|
|
1048
|
+
const added = {
|
|
1049
|
+
id: title.toLowerCase().replace(/\s+/g, "_"),
|
|
1050
|
+
title,
|
|
1051
|
+
fieldType: ft,
|
|
1052
|
+
value,
|
|
1053
|
+
};
|
|
1054
|
+
if (sectionId) added.sectionId = sectionId;
|
|
1055
|
+
fieldIndexByTitle.set(key, nextFields.length);
|
|
1056
|
+
nextFields.push(added);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
if (Array.isArray(args.fields)) {
|
|
1060
|
+
for (const patch of args.fields) upsertField(patch);
|
|
991
1061
|
}
|
|
992
1062
|
|
|
1063
|
+
// --- notes: stored as a 'notesPlain' Text field, so patch it the same way ---
|
|
1064
|
+
if (args.notes !== undefined) {
|
|
1065
|
+
upsertField({ title: "notesPlain", value: args.notes, type: "Text" });
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
updated.fields = nextFields;
|
|
1069
|
+
|
|
993
1070
|
const result = await client.items.put(updated);
|
|
994
1071
|
return `Updated item "${result.title}" (id: ${result.id}) in vault "${vault.title}".`;
|
|
995
1072
|
}
|
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.5",
|
|
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": {
|