payload-mcp-toolkit 0.3.0 → 0.3.2
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 +3 -3
- package/dist/draft-workflow.d.ts +5 -4
- package/dist/draft-workflow.js +15 -7
- package/dist/draft-workflow.js.map +1 -1
- package/dist/index.js +6 -19
- package/dist/index.js.map +1 -1
- package/dist/introspection.d.ts +4 -0
- package/dist/introspection.js +7 -2
- package/dist/introspection.js.map +1 -1
- package/dist/resources.js +1 -8
- package/dist/resources.js.map +1 -1
- package/dist/tools/_helpers.d.ts +14 -0
- package/dist/tools/_helpers.js +35 -0
- package/dist/tools/_helpers.js.map +1 -0
- package/dist/tools/patch-layout.d.ts +3 -9
- package/dist/tools/patch-layout.js +29 -48
- package/dist/tools/patch-layout.js.map +1 -1
- package/dist/tools/publish-draft.d.ts +1 -11
- package/dist/tools/publish-draft.js +8 -39
- package/dist/tools/publish-draft.js.map +1 -1
- package/dist/tools/resolve-reference.d.ts +1 -12
- package/dist/tools/resolve-reference.js +45 -85
- package/dist/tools/resolve-reference.js.map +1 -1
- package/dist/tools/safe-delete.d.ts +8 -13
- package/dist/tools/safe-delete.js +68 -100
- package/dist/tools/safe-delete.js.map +1 -1
- package/dist/tools/schedule-publish.d.ts +11 -21
- package/dist/tools/schedule-publish.js +18 -61
- package/dist/tools/schedule-publish.js.map +1 -1
- package/dist/tools/search-content.d.ts +1 -6
- package/dist/tools/search-content.js +52 -64
- package/dist/tools/search-content.js.map +1 -1
- package/dist/tools/update-document.d.ts +4 -14
- package/dist/tools/update-document.js +23 -72
- package/dist/tools/update-document.js.map +1 -1
- package/dist/tools/upload-media.d.ts +1 -10
- package/dist/tools/upload-media.js +11 -54
- package/dist/tools/upload-media.js.map +1 -1
- package/dist/tools/versions.d.ts +7 -20
- package/dist/tools/versions.js +25 -82
- package/dist/tools/versions.js.map +1 -1
- package/package.json +1 -1
- package/dist/rate-limiter.d.ts +0 -25
- package/dist/rate-limiter.js +0 -51
- package/dist/rate-limiter.js.map +0 -1
package/dist/tools/versions.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PayloadRequest } from 'payload';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* compact display name per version so an LLM can pick one to restore.
|
|
4
|
+
* Lists recent saved versions of a draft document. Returns id, _status,
|
|
5
|
+
* updatedAt, and a compact display name per version so an LLM can pick one
|
|
6
|
+
* to restore.
|
|
8
7
|
*/
|
|
9
8
|
export declare function createListVersionsTool(draftCollections: Set<string>): {
|
|
10
9
|
name: string;
|
|
@@ -18,18 +17,11 @@ export declare function createListVersionsTool(draftCollections: Set<string>): {
|
|
|
18
17
|
collection: string;
|
|
19
18
|
documentId: string;
|
|
20
19
|
limit?: number;
|
|
21
|
-
}, req: PayloadRequest, _extra: unknown) => Promise<
|
|
22
|
-
content: {
|
|
23
|
-
type: "text";
|
|
24
|
-
text: string;
|
|
25
|
-
}[];
|
|
26
|
-
}>;
|
|
20
|
+
}, req: PayloadRequest, _extra: unknown) => Promise<import("./_helpers").McpTextResponse>;
|
|
27
21
|
};
|
|
28
22
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* Restoring a version creates a new version on top — the old current state is preserved
|
|
32
|
-
* so the operation is itself reversible via another restore.
|
|
23
|
+
* Restoring a version creates a new version on top — the previous current
|
|
24
|
+
* state is preserved so the operation is itself reversible.
|
|
33
25
|
*/
|
|
34
26
|
export declare function createRestoreVersionTool(draftCollections: Set<string>): {
|
|
35
27
|
name: string;
|
|
@@ -41,10 +33,5 @@ export declare function createRestoreVersionTool(draftCollections: Set<string>):
|
|
|
41
33
|
handler: (args: {
|
|
42
34
|
collection: string;
|
|
43
35
|
versionId: string;
|
|
44
|
-
}, req: PayloadRequest, _extra: unknown) => Promise<
|
|
45
|
-
content: {
|
|
46
|
-
type: "text";
|
|
47
|
-
text: string;
|
|
48
|
-
}[];
|
|
49
|
-
}>;
|
|
36
|
+
}, req: PayloadRequest, _extra: unknown) => Promise<import("./_helpers").McpTextResponse>;
|
|
50
37
|
};
|
package/dist/tools/versions.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { errorMessage, getDocDisplayName, jsonResponse, requireDraftCollection, stampMcpContext, textResponse } from './_helpers';
|
|
2
3
|
const DEFAULT_LIST_LIMIT = 10;
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* compact display name per version so an LLM can pick one to restore.
|
|
5
|
+
* Lists recent saved versions of a draft document. Returns id, _status,
|
|
6
|
+
* updatedAt, and a compact display name per version so an LLM can pick one
|
|
7
|
+
* to restore.
|
|
8
8
|
*/ export function createListVersionsTool(draftCollections) {
|
|
9
9
|
return {
|
|
10
10
|
name: 'listVersions',
|
|
@@ -20,22 +20,9 @@ const DEFAULT_LIST_LIMIT = 10;
|
|
|
20
20
|
},
|
|
21
21
|
handler: async (args, req, _extra)=>{
|
|
22
22
|
const { collection, documentId, limit = DEFAULT_LIST_LIMIT } = args;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
{
|
|
27
|
-
type: 'text',
|
|
28
|
-
text: `Error: Collection "${collection}" does not support versions. ` + `Draft-enabled collections: ${[
|
|
29
|
-
...draftCollections
|
|
30
|
-
].join(', ') || 'none'}`
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
req.context = {
|
|
36
|
-
...req.context,
|
|
37
|
-
source: 'mcp'
|
|
38
|
-
};
|
|
23
|
+
const guard = requireDraftCollection(collection, draftCollections, 'versions');
|
|
24
|
+
if (guard) return guard;
|
|
25
|
+
stampMcpContext(req);
|
|
39
26
|
try {
|
|
40
27
|
const result = await req.payload.findVersions({
|
|
41
28
|
collection: collection,
|
|
@@ -57,43 +44,26 @@ const DEFAULT_LIST_LIMIT = 10;
|
|
|
57
44
|
updatedAt: v.updatedAt,
|
|
58
45
|
createdAt: v.createdAt,
|
|
59
46
|
status: snapshot._status ?? 'unknown',
|
|
60
|
-
displayName: snapshot
|
|
47
|
+
displayName: getDocDisplayName(snapshot, `${collection}#${documentId}`),
|
|
61
48
|
autosave: v.autosave === true
|
|
62
49
|
};
|
|
63
50
|
});
|
|
64
|
-
return {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
totalDocs: result.totalDocs,
|
|
72
|
-
returned: versions.length,
|
|
73
|
-
versions
|
|
74
|
-
})
|
|
75
|
-
}
|
|
76
|
-
]
|
|
77
|
-
};
|
|
51
|
+
return jsonResponse({
|
|
52
|
+
collection,
|
|
53
|
+
documentId,
|
|
54
|
+
totalDocs: result.totalDocs,
|
|
55
|
+
returned: versions.length,
|
|
56
|
+
versions
|
|
57
|
+
});
|
|
78
58
|
} catch (error) {
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
content: [
|
|
82
|
-
{
|
|
83
|
-
type: 'text',
|
|
84
|
-
text: `Error listing versions for ${collection}#${documentId}: ${message}`
|
|
85
|
-
}
|
|
86
|
-
]
|
|
87
|
-
};
|
|
59
|
+
return textResponse(`Error listing versions for ${collection}#${documentId}: ${errorMessage(error)}`);
|
|
88
60
|
}
|
|
89
61
|
}
|
|
90
62
|
};
|
|
91
63
|
}
|
|
92
64
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* Restoring a version creates a new version on top — the old current state is preserved
|
|
96
|
-
* so the operation is itself reversible via another restore.
|
|
65
|
+
* Restoring a version creates a new version on top — the previous current
|
|
66
|
+
* state is preserved so the operation is itself reversible.
|
|
97
67
|
*/ export function createRestoreVersionTool(draftCollections) {
|
|
98
68
|
return {
|
|
99
69
|
name: 'restoreVersion',
|
|
@@ -108,22 +78,9 @@ const DEFAULT_LIST_LIMIT = 10;
|
|
|
108
78
|
},
|
|
109
79
|
handler: async (args, req, _extra)=>{
|
|
110
80
|
const { collection, versionId } = args;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
{
|
|
115
|
-
type: 'text',
|
|
116
|
-
text: `Error: Collection "${collection}" does not support versions. ` + `Draft-enabled collections: ${[
|
|
117
|
-
...draftCollections
|
|
118
|
-
].join(', ') || 'none'}`
|
|
119
|
-
}
|
|
120
|
-
]
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
req.context = {
|
|
124
|
-
...req.context,
|
|
125
|
-
source: 'mcp'
|
|
126
|
-
};
|
|
81
|
+
const guard = requireDraftCollection(collection, draftCollections, 'versions');
|
|
82
|
+
if (guard) return guard;
|
|
83
|
+
stampMcpContext(req);
|
|
127
84
|
try {
|
|
128
85
|
const restored = await req.payload.restoreVersion({
|
|
129
86
|
collection: collection,
|
|
@@ -132,25 +89,11 @@ const DEFAULT_LIST_LIMIT = 10;
|
|
|
132
89
|
overrideAccess: false,
|
|
133
90
|
user: req.user
|
|
134
91
|
});
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
{
|
|
139
|
-
type: 'text',
|
|
140
|
-
text: `Restored ${collection} document "${displayName}" (ID: ${restored.id}) ` + `from version ${versionId}. The document is now in draft status — ` + `use publishDraft to make the restored content live.`
|
|
141
|
-
}
|
|
142
|
-
]
|
|
143
|
-
};
|
|
92
|
+
const restoredId = String(restored.id);
|
|
93
|
+
const displayName = getDocDisplayName(restored, restoredId);
|
|
94
|
+
return textResponse(`Restored ${collection} document "${displayName}" (ID: ${restoredId}) ` + `from version ${versionId}. The document is now in draft status — ` + `use publishDraft to make the restored content live.`);
|
|
144
95
|
} catch (error) {
|
|
145
|
-
|
|
146
|
-
return {
|
|
147
|
-
content: [
|
|
148
|
-
{
|
|
149
|
-
type: 'text',
|
|
150
|
-
text: `Error restoring ${collection} from version ${versionId}: ${message}`
|
|
151
|
-
}
|
|
152
|
-
]
|
|
153
|
-
};
|
|
96
|
+
return textResponse(`Error restoring ${collection} from version ${versionId}: ${errorMessage(error)}`);
|
|
154
97
|
}
|
|
155
98
|
}
|
|
156
99
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/tools/versions.ts"],"sourcesContent":["import { z } from 'zod'\nimport type { PayloadRequest } from 'payload'\n\nconst DEFAULT_LIST_LIMIT = 10\n\n/**\n * Creates the listVersions MCP tool that returns recent saved versions of a draft document.\n *\n * Only works on collections in `draftCollections`. Returns id, _status, updatedAt, and a\n * compact display name per version so an LLM can pick one to restore.\n */\nexport function createListVersionsTool(draftCollections: Set<string>) {\n return {\n name: 'listVersions',\n description:\n 'List recent saved versions of a document on a draft-enabled collection. ' +\n 'Use before restoreVersion to pick the right point in time. ' +\n `Draft-enabled collections: ${[...draftCollections].join(', ') || 'none'}`,\n parameters: {\n collection: z\n .string()\n .describe(\n `The collection slug. Must be one of: ${[...draftCollections].join(', ') || 'none'}`,\n ),\n documentId: z.string().describe('The ID of the document whose versions you want to list'),\n limit: z\n .number()\n .optional()\n .default(DEFAULT_LIST_LIMIT)\n .describe(`Maximum number of versions to return (default ${DEFAULT_LIST_LIMIT})`),\n },\n handler: async (\n args: { collection: string; documentId: string; limit?: number },\n req: PayloadRequest,\n _extra: unknown,\n ) => {\n const { collection, documentId, limit = DEFAULT_LIST_LIMIT } = args\n\n if (!draftCollections.has(collection)) {\n return {\n content: [\n {\n type: 'text' as const,\n text:\n `Error: Collection \"${collection}\" does not support versions. ` +\n `Draft-enabled collections: ${[...draftCollections].join(', ') || 'none'}`,\n },\n ],\n }\n }\n\n req.context = { ...req.context, source: 'mcp' }\n\n try {\n const result = await req.payload.findVersions({\n collection: collection as any,\n where: { parent: { equals: documentId } },\n sort: '-updatedAt',\n limit,\n req,\n overrideAccess: false,\n user: req.user,\n })\n\n const versions = result.docs.map((v: any) => {\n const snapshot = v.version || {}\n return {\n id: v.id,\n updatedAt: v.updatedAt,\n createdAt: v.createdAt,\n status: snapshot._status ?? 'unknown',\n displayName:\n snapshot.name ||\n snapshot.title ||\n snapshot.slug ||\n `${collection}#${documentId}`,\n autosave: v.autosave === true,\n }\n })\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({\n collection,\n documentId,\n totalDocs: result.totalDocs,\n returned: versions.length,\n versions,\n }),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error listing versions for ${collection}#${documentId}: ${message}`,\n },\n ],\n }\n }\n },\n }\n}\n\n/**\n * Creates the restoreVersion MCP tool that rolls a document back to a saved version.\n *\n * Restoring a version creates a new version on top — the old current state is preserved\n * so the operation is itself reversible via another restore.\n */\nexport function createRestoreVersionTool(draftCollections: Set<string>) {\n return {\n name: 'restoreVersion',\n description:\n 'Restore a document to a previously saved version. ' +\n 'Use listVersions first to find the version ID. ' +\n 'Restoring creates a new version on top, so the previous current state is also recoverable. ' +\n `Draft-enabled collections: ${[...draftCollections].join(', ') || 'none'}`,\n parameters: {\n collection: z\n .string()\n .describe(\n `The collection slug. Must be one of: ${[...draftCollections].join(', ') || 'none'}`,\n ),\n versionId: z\n .string()\n .describe('The version ID returned by listVersions (NOT the document ID)'),\n },\n handler: async (\n args: { collection: string; versionId: string },\n req: PayloadRequest,\n _extra: unknown,\n ) => {\n const { collection, versionId } = args\n\n if (!draftCollections.has(collection)) {\n return {\n content: [\n {\n type: 'text' as const,\n text:\n `Error: Collection \"${collection}\" does not support versions. ` +\n `Draft-enabled collections: ${[...draftCollections].join(', ') || 'none'}`,\n },\n ],\n }\n }\n\n req.context = { ...req.context, source: 'mcp' }\n\n try {\n const restored = await req.payload.restoreVersion({\n collection: collection as any,\n id: versionId,\n req,\n overrideAccess: false,\n user: req.user,\n })\n\n const displayName =\n (restored as any).name ||\n (restored as any).title ||\n (restored as any).slug ||\n (restored as any).id\n\n return {\n content: [\n {\n type: 'text' as const,\n text:\n `Restored ${collection} document \"${displayName}\" (ID: ${(restored as any).id}) ` +\n `from version ${versionId}. The document is now in draft status — ` +\n `use publishDraft to make the restored content live.`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error restoring ${collection} from version ${versionId}: ${message}`,\n },\n ],\n }\n }\n },\n }\n}\n"],"names":["z","DEFAULT_LIST_LIMIT","createListVersionsTool","draftCollections","name","description","join","parameters","collection","string","describe","documentId","limit","number","optional","default","handler","args","req","_extra","has","content","type","text","context","source","result","payload","findVersions","where","parent","equals","sort","overrideAccess","user","versions","docs","map","v","snapshot","version","id","updatedAt","createdAt","status","_status","displayName","title","slug","autosave","JSON","stringify","totalDocs","returned","length","error","message","Error","String","createRestoreVersionTool","versionId","restored","restoreVersion"],"mappings":"AAAA,SAASA,CAAC,QAAQ,MAAK;AAGvB,MAAMC,qBAAqB;AAE3B;;;;;CAKC,GACD,OAAO,SAASC,uBAAuBC,gBAA6B;IAClE,OAAO;QACLC,MAAM;QACNC,aACE,6EACA,gEACA,CAAC,2BAA2B,EAAE;eAAIF;SAAiB,CAACG,IAAI,CAAC,SAAS,QAAQ;QAC5EC,YAAY;YACVC,YAAYR,EACTS,MAAM,GACNC,QAAQ,CACP,CAAC,qCAAqC,EAAE;mBAAIP;aAAiB,CAACG,IAAI,CAAC,SAAS,QAAQ;YAExFK,YAAYX,EAAES,MAAM,GAAGC,QAAQ,CAAC;YAChCE,OAAOZ,EACJa,MAAM,GACNC,QAAQ,GACRC,OAAO,CAACd,oBACRS,QAAQ,CAAC,CAAC,8CAA8C,EAAET,mBAAmB,CAAC,CAAC;QACpF;QACAe,SAAS,OACPC,MACAC,KACAC;YAEA,MAAM,EAAEX,UAAU,EAAEG,UAAU,EAAEC,QAAQX,kBAAkB,EAAE,GAAGgB;YAE/D,IAAI,CAACd,iBAAiBiB,GAAG,CAACZ,aAAa;gBACrC,OAAO;oBACLa,SAAS;wBACP;4BACEC,MAAM;4BACNC,MACE,CAAC,mBAAmB,EAAEf,WAAW,6BAA6B,CAAC,GAC/D,CAAC,2BAA2B,EAAE;mCAAIL;6BAAiB,CAACG,IAAI,CAAC,SAAS,QAAQ;wBAC9E;qBACD;gBACH;YACF;YAEAY,IAAIM,OAAO,GAAG;gBAAE,GAAGN,IAAIM,OAAO;gBAAEC,QAAQ;YAAM;YAE9C,IAAI;gBACF,MAAMC,SAAS,MAAMR,IAAIS,OAAO,CAACC,YAAY,CAAC;oBAC5CpB,YAAYA;oBACZqB,OAAO;wBAAEC,QAAQ;4BAAEC,QAAQpB;wBAAW;oBAAE;oBACxCqB,MAAM;oBACNpB;oBACAM;oBACAe,gBAAgB;oBAChBC,MAAMhB,IAAIgB,IAAI;gBAChB;gBAEA,MAAMC,WAAWT,OAAOU,IAAI,CAACC,GAAG,CAAC,CAACC;oBAChC,MAAMC,WAAWD,EAAEE,OAAO,IAAI,CAAC;oBAC/B,OAAO;wBACLC,IAAIH,EAAEG,EAAE;wBACRC,WAAWJ,EAAEI,SAAS;wBACtBC,WAAWL,EAAEK,SAAS;wBACtBC,QAAQL,SAASM,OAAO,IAAI;wBAC5BC,aACEP,SAASnC,IAAI,IACbmC,SAASQ,KAAK,IACdR,SAASS,IAAI,IACb,GAAGxC,WAAW,CAAC,EAAEG,YAAY;wBAC/BsC,UAAUX,EAAEW,QAAQ,KAAK;oBAC3B;gBACF;gBAEA,OAAO;oBACL5B,SAAS;wBACP;4BACEC,MAAM;4BACNC,MAAM2B,KAAKC,SAAS,CAAC;gCACnB3C;gCACAG;gCACAyC,WAAW1B,OAAO0B,SAAS;gCAC3BC,UAAUlB,SAASmB,MAAM;gCACzBnB;4BACF;wBACF;qBACD;gBACH;YACF,EAAE,OAAOoB,OAAO;gBACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;gBAChE,OAAO;oBACLlC,SAAS;wBACP;4BACEC,MAAM;4BACNC,MAAM,CAAC,2BAA2B,EAAEf,WAAW,CAAC,EAAEG,WAAW,EAAE,EAAE6C,SAAS;wBAC5E;qBACD;gBACH;YACF;QACF;IACF;AACF;AAEA;;;;;CAKC,GACD,OAAO,SAASG,yBAAyBxD,gBAA6B;IACpE,OAAO;QACLC,MAAM;QACNC,aACE,uDACA,oDACA,gGACA,CAAC,2BAA2B,EAAE;eAAIF;SAAiB,CAACG,IAAI,CAAC,SAAS,QAAQ;QAC5EC,YAAY;YACVC,YAAYR,EACTS,MAAM,GACNC,QAAQ,CACP,CAAC,qCAAqC,EAAE;mBAAIP;aAAiB,CAACG,IAAI,CAAC,SAAS,QAAQ;YAExFsD,WAAW5D,EACRS,MAAM,GACNC,QAAQ,CAAC;QACd;QACAM,SAAS,OACPC,MACAC,KACAC;YAEA,MAAM,EAAEX,UAAU,EAAEoD,SAAS,EAAE,GAAG3C;YAElC,IAAI,CAACd,iBAAiBiB,GAAG,CAACZ,aAAa;gBACrC,OAAO;oBACLa,SAAS;wBACP;4BACEC,MAAM;4BACNC,MACE,CAAC,mBAAmB,EAAEf,WAAW,6BAA6B,CAAC,GAC/D,CAAC,2BAA2B,EAAE;mCAAIL;6BAAiB,CAACG,IAAI,CAAC,SAAS,QAAQ;wBAC9E;qBACD;gBACH;YACF;YAEAY,IAAIM,OAAO,GAAG;gBAAE,GAAGN,IAAIM,OAAO;gBAAEC,QAAQ;YAAM;YAE9C,IAAI;gBACF,MAAMoC,WAAW,MAAM3C,IAAIS,OAAO,CAACmC,cAAc,CAAC;oBAChDtD,YAAYA;oBACZiC,IAAImB;oBACJ1C;oBACAe,gBAAgB;oBAChBC,MAAMhB,IAAIgB,IAAI;gBAChB;gBAEA,MAAMY,cACJ,AAACe,SAAiBzD,IAAI,IACtB,AAACyD,SAAiBd,KAAK,IACvB,AAACc,SAAiBb,IAAI,IACtB,AAACa,SAAiBpB,EAAE;gBAEtB,OAAO;oBACLpB,SAAS;wBACP;4BACEC,MAAM;4BACNC,MACE,CAAC,SAAS,EAAEf,WAAW,WAAW,EAAEsC,YAAY,OAAO,EAAE,AAACe,SAAiBpB,EAAE,CAAC,EAAE,CAAC,GACjF,CAAC,aAAa,EAAEmB,UAAU,wCAAwC,CAAC,GACnE,CAAC,mDAAmD,CAAC;wBACzD;qBACD;gBACH;YACF,EAAE,OAAOL,OAAO;gBACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;gBAChE,OAAO;oBACLlC,SAAS;wBACP;4BACEC,MAAM;4BACNC,MAAM,CAAC,gBAAgB,EAAEf,WAAW,cAAc,EAAEoD,UAAU,EAAE,EAAEJ,SAAS;wBAC7E;qBACD;gBACH;YACF;QACF;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/tools/versions.ts"],"sourcesContent":["import { z } from 'zod'\nimport type { PayloadRequest } from 'payload'\nimport {\n errorMessage,\n getDocDisplayName,\n jsonResponse,\n requireDraftCollection,\n stampMcpContext,\n textResponse,\n} from './_helpers'\n\nconst DEFAULT_LIST_LIMIT = 10\n\n/**\n * Lists recent saved versions of a draft document. Returns id, _status,\n * updatedAt, and a compact display name per version so an LLM can pick one\n * to restore.\n */\nexport function createListVersionsTool(draftCollections: Set<string>) {\n return {\n name: 'listVersions',\n description:\n 'List recent saved versions of a document on a draft-enabled collection. ' +\n 'Use before restoreVersion to pick the right point in time. ' +\n `Draft-enabled collections: ${[...draftCollections].join(', ') || 'none'}`,\n parameters: {\n collection: z\n .string()\n .describe(\n `The collection slug. Must be one of: ${[...draftCollections].join(', ') || 'none'}`,\n ),\n documentId: z.string().describe('The ID of the document whose versions you want to list'),\n limit: z\n .number()\n .optional()\n .default(DEFAULT_LIST_LIMIT)\n .describe(`Maximum number of versions to return (default ${DEFAULT_LIST_LIMIT})`),\n },\n handler: async (\n args: { collection: string; documentId: string; limit?: number },\n req: PayloadRequest,\n _extra: unknown,\n ) => {\n const { collection, documentId, limit = DEFAULT_LIST_LIMIT } = args\n\n const guard = requireDraftCollection(collection, draftCollections, 'versions')\n if (guard) return guard\n\n stampMcpContext(req)\n\n try {\n const result = await req.payload.findVersions({\n collection: collection as any,\n where: { parent: { equals: documentId } },\n sort: '-updatedAt',\n limit,\n req,\n overrideAccess: false,\n user: req.user,\n })\n\n const versions = result.docs.map((v: any) => {\n const snapshot = v.version || {}\n return {\n id: v.id,\n updatedAt: v.updatedAt,\n createdAt: v.createdAt,\n status: snapshot._status ?? 'unknown',\n displayName: getDocDisplayName(snapshot, `${collection}#${documentId}`),\n autosave: v.autosave === true,\n }\n })\n\n return jsonResponse({\n collection,\n documentId,\n totalDocs: result.totalDocs,\n returned: versions.length,\n versions,\n })\n } catch (error) {\n return textResponse(\n `Error listing versions for ${collection}#${documentId}: ${errorMessage(error)}`,\n )\n }\n },\n }\n}\n\n/**\n * Restoring a version creates a new version on top — the previous current\n * state is preserved so the operation is itself reversible.\n */\nexport function createRestoreVersionTool(draftCollections: Set<string>) {\n return {\n name: 'restoreVersion',\n description:\n 'Restore a document to a previously saved version. ' +\n 'Use listVersions first to find the version ID. ' +\n 'Restoring creates a new version on top, so the previous current state is also recoverable. ' +\n `Draft-enabled collections: ${[...draftCollections].join(', ') || 'none'}`,\n parameters: {\n collection: z\n .string()\n .describe(\n `The collection slug. Must be one of: ${[...draftCollections].join(', ') || 'none'}`,\n ),\n versionId: z\n .string()\n .describe('The version ID returned by listVersions (NOT the document ID)'),\n },\n handler: async (\n args: { collection: string; versionId: string },\n req: PayloadRequest,\n _extra: unknown,\n ) => {\n const { collection, versionId } = args\n\n const guard = requireDraftCollection(collection, draftCollections, 'versions')\n if (guard) return guard\n\n stampMcpContext(req)\n\n try {\n const restored = await req.payload.restoreVersion({\n collection: collection as any,\n id: versionId,\n req,\n overrideAccess: false,\n user: req.user,\n })\n\n const restoredId = String((restored as any).id)\n const displayName = getDocDisplayName(restored, restoredId)\n\n return textResponse(\n `Restored ${collection} document \"${displayName}\" (ID: ${restoredId}) ` +\n `from version ${versionId}. The document is now in draft status — ` +\n `use publishDraft to make the restored content live.`,\n )\n } catch (error) {\n return textResponse(\n `Error restoring ${collection} from version ${versionId}: ${errorMessage(error)}`,\n )\n }\n },\n }\n}\n"],"names":["z","errorMessage","getDocDisplayName","jsonResponse","requireDraftCollection","stampMcpContext","textResponse","DEFAULT_LIST_LIMIT","createListVersionsTool","draftCollections","name","description","join","parameters","collection","string","describe","documentId","limit","number","optional","default","handler","args","req","_extra","guard","result","payload","findVersions","where","parent","equals","sort","overrideAccess","user","versions","docs","map","v","snapshot","version","id","updatedAt","createdAt","status","_status","displayName","autosave","totalDocs","returned","length","error","createRestoreVersionTool","versionId","restored","restoreVersion","restoredId","String"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payload-mcp-toolkit",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Schema-aware MCP toolkit for Payload CMS — wraps the official @payloadcms/plugin-mcp with introspected prompts, resources, draft workflow, and AI-friendly tools so non-technical editors can manage content via AI chat.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "jon8800",
|
package/dist/rate-limiter.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple in-memory sliding window rate limiter per API key.
|
|
3
|
-
* State resets on server restart — not suitable for serverless.
|
|
4
|
-
*/
|
|
5
|
-
interface RateLimitOptions {
|
|
6
|
-
/** Window duration in milliseconds (default: 60000 = 1 minute) */
|
|
7
|
-
windowMs?: number;
|
|
8
|
-
/** Maximum requests per window (default: 60) */
|
|
9
|
-
maxRequests?: number;
|
|
10
|
-
}
|
|
11
|
-
export declare function createRateLimiter(options?: RateLimitOptions): {
|
|
12
|
-
/**
|
|
13
|
-
* Check if a request is allowed for the given key.
|
|
14
|
-
* Returns { allowed: true } or { allowed: false, retryAfterMs }.
|
|
15
|
-
*/
|
|
16
|
-
check(key: string): {
|
|
17
|
-
allowed: true;
|
|
18
|
-
} | {
|
|
19
|
-
allowed: false;
|
|
20
|
-
retryAfterMs: number;
|
|
21
|
-
};
|
|
22
|
-
/** Reset the store (for testing) */
|
|
23
|
-
reset(): void;
|
|
24
|
-
};
|
|
25
|
-
export {};
|
package/dist/rate-limiter.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple in-memory sliding window rate limiter per API key.
|
|
3
|
-
* State resets on server restart — not suitable for serverless.
|
|
4
|
-
*/ const DEFAULT_WINDOW_MS = 60_000;
|
|
5
|
-
const DEFAULT_MAX_REQUESTS = 60;
|
|
6
|
-
export function createRateLimiter(options) {
|
|
7
|
-
const windowMs = options?.windowMs ?? DEFAULT_WINDOW_MS;
|
|
8
|
-
const maxRequests = options?.maxRequests ?? DEFAULT_MAX_REQUESTS;
|
|
9
|
-
const store = new Map();
|
|
10
|
-
// Periodically clean up expired entries (every 5 minutes)
|
|
11
|
-
const cleanupInterval = setInterval(()=>{
|
|
12
|
-
const now = Date.now();
|
|
13
|
-
for (const [key, entry] of store){
|
|
14
|
-
entry.timestamps = entry.timestamps.filter((t)=>now - t < windowMs);
|
|
15
|
-
if (entry.timestamps.length === 0) store.delete(key);
|
|
16
|
-
}
|
|
17
|
-
}, 5 * 60_000);
|
|
18
|
-
// Allow garbage collection if the module is unloaded
|
|
19
|
-
if (cleanupInterval.unref) cleanupInterval.unref();
|
|
20
|
-
return {
|
|
21
|
-
/**
|
|
22
|
-
* Check if a request is allowed for the given key.
|
|
23
|
-
* Returns { allowed: true } or { allowed: false, retryAfterMs }.
|
|
24
|
-
*/ check (key) {
|
|
25
|
-
const now = Date.now();
|
|
26
|
-
const entry = store.get(key) ?? {
|
|
27
|
-
timestamps: []
|
|
28
|
-
};
|
|
29
|
-
// Remove timestamps outside the window
|
|
30
|
-
entry.timestamps = entry.timestamps.filter((t)=>now - t < windowMs);
|
|
31
|
-
if (entry.timestamps.length >= maxRequests) {
|
|
32
|
-
const oldest = entry.timestamps[0];
|
|
33
|
-
const retryAfterMs = oldest + windowMs - now;
|
|
34
|
-
return {
|
|
35
|
-
allowed: false,
|
|
36
|
-
retryAfterMs: Math.max(retryAfterMs, 1000)
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
entry.timestamps.push(now);
|
|
40
|
-
store.set(key, entry);
|
|
41
|
-
return {
|
|
42
|
-
allowed: true
|
|
43
|
-
};
|
|
44
|
-
},
|
|
45
|
-
/** Reset the store (for testing) */ reset () {
|
|
46
|
-
store.clear();
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
//# sourceMappingURL=rate-limiter.js.map
|
package/dist/rate-limiter.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rate-limiter.ts"],"sourcesContent":["/**\n * Simple in-memory sliding window rate limiter per API key.\n * State resets on server restart — not suitable for serverless.\n */\n\ninterface RateLimitEntry {\n timestamps: number[]\n}\n\ninterface RateLimitOptions {\n /** Window duration in milliseconds (default: 60000 = 1 minute) */\n windowMs?: number\n /** Maximum requests per window (default: 60) */\n maxRequests?: number\n}\n\nconst DEFAULT_WINDOW_MS = 60_000\nconst DEFAULT_MAX_REQUESTS = 60\n\nexport function createRateLimiter(options?: RateLimitOptions) {\n const windowMs = options?.windowMs ?? DEFAULT_WINDOW_MS\n const maxRequests = options?.maxRequests ?? DEFAULT_MAX_REQUESTS\n const store = new Map<string, RateLimitEntry>()\n\n // Periodically clean up expired entries (every 5 minutes)\n const cleanupInterval = setInterval(() => {\n const now = Date.now()\n for (const [key, entry] of store) {\n entry.timestamps = entry.timestamps.filter((t) => now - t < windowMs)\n if (entry.timestamps.length === 0) store.delete(key)\n }\n }, 5 * 60_000)\n\n // Allow garbage collection if the module is unloaded\n if (cleanupInterval.unref) cleanupInterval.unref()\n\n return {\n /**\n * Check if a request is allowed for the given key.\n * Returns { allowed: true } or { allowed: false, retryAfterMs }.\n */\n check(key: string): { allowed: true } | { allowed: false; retryAfterMs: number } {\n const now = Date.now()\n const entry = store.get(key) ?? { timestamps: [] }\n\n // Remove timestamps outside the window\n entry.timestamps = entry.timestamps.filter((t) => now - t < windowMs)\n\n if (entry.timestamps.length >= maxRequests) {\n const oldest = entry.timestamps[0]\n const retryAfterMs = oldest + windowMs - now\n return { allowed: false, retryAfterMs: Math.max(retryAfterMs, 1000) }\n }\n\n entry.timestamps.push(now)\n store.set(key, entry)\n return { allowed: true }\n },\n\n /** Reset the store (for testing) */\n reset() {\n store.clear()\n },\n }\n}\n"],"names":["DEFAULT_WINDOW_MS","DEFAULT_MAX_REQUESTS","createRateLimiter","options","windowMs","maxRequests","store","Map","cleanupInterval","setInterval","now","Date","key","entry","timestamps","filter","t","length","delete","unref","check","get","oldest","retryAfterMs","allowed","Math","max","push","set","reset","clear"],"mappings":"AAAA;;;CAGC,GAaD,MAAMA,oBAAoB;AAC1B,MAAMC,uBAAuB;AAE7B,OAAO,SAASC,kBAAkBC,OAA0B;IAC1D,MAAMC,WAAWD,SAASC,YAAYJ;IACtC,MAAMK,cAAcF,SAASE,eAAeJ;IAC5C,MAAMK,QAAQ,IAAIC;IAElB,0DAA0D;IAC1D,MAAMC,kBAAkBC,YAAY;QAClC,MAAMC,MAAMC,KAAKD,GAAG;QACpB,KAAK,MAAM,CAACE,KAAKC,MAAM,IAAIP,MAAO;YAChCO,MAAMC,UAAU,GAAGD,MAAMC,UAAU,CAACC,MAAM,CAAC,CAACC,IAAMN,MAAMM,IAAIZ;YAC5D,IAAIS,MAAMC,UAAU,CAACG,MAAM,KAAK,GAAGX,MAAMY,MAAM,CAACN;QAClD;IACF,GAAG,IAAI;IAEP,qDAAqD;IACrD,IAAIJ,gBAAgBW,KAAK,EAAEX,gBAAgBW,KAAK;IAEhD,OAAO;QACL;;;KAGC,GACDC,OAAMR,GAAW;YACf,MAAMF,MAAMC,KAAKD,GAAG;YACpB,MAAMG,QAAQP,MAAMe,GAAG,CAACT,QAAQ;gBAAEE,YAAY,EAAE;YAAC;YAEjD,uCAAuC;YACvCD,MAAMC,UAAU,GAAGD,MAAMC,UAAU,CAACC,MAAM,CAAC,CAACC,IAAMN,MAAMM,IAAIZ;YAE5D,IAAIS,MAAMC,UAAU,CAACG,MAAM,IAAIZ,aAAa;gBAC1C,MAAMiB,SAAST,MAAMC,UAAU,CAAC,EAAE;gBAClC,MAAMS,eAAeD,SAASlB,WAAWM;gBACzC,OAAO;oBAAEc,SAAS;oBAAOD,cAAcE,KAAKC,GAAG,CAACH,cAAc;gBAAM;YACtE;YAEAV,MAAMC,UAAU,CAACa,IAAI,CAACjB;YACtBJ,MAAMsB,GAAG,CAAChB,KAAKC;YACf,OAAO;gBAAEW,SAAS;YAAK;QACzB;QAEA,kCAAkC,GAClCK;YACEvB,MAAMwB,KAAK;QACb;IACF;AACF"}
|