@reverso/mcp 0.1.0
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 +64 -0
- package/dist/bin.d.ts +10 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +87 -0
- package/dist/bin.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +51 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +193 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/content.d.ts +177 -0
- package/dist/tools/content.d.ts.map +1 -0
- package/dist/tools/content.js +143 -0
- package/dist/tools/content.js.map +1 -0
- package/dist/tools/forms.d.ts +197 -0
- package/dist/tools/forms.d.ts.map +1 -0
- package/dist/tools/forms.js +132 -0
- package/dist/tools/forms.js.map +1 -0
- package/dist/tools/generation.d.ts +98 -0
- package/dist/tools/generation.d.ts.map +1 -0
- package/dist/tools/generation.js +213 -0
- package/dist/tools/generation.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +9 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/media.d.ts +160 -0
- package/dist/tools/media.d.ts.map +1 -0
- package/dist/tools/media.js +143 -0
- package/dist/tools/media.js.map +1 -0
- package/dist/tools/schema.d.ts +86 -0
- package/dist/tools/schema.d.ts.map +1 -0
- package/dist/tools/schema.js +263 -0
- package/dist/tools/schema.js.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content management tools for the MCP server.
|
|
3
|
+
*/
|
|
4
|
+
import type { DrizzleDatabase } from '@reverso/db';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export declare const contentTools: {
|
|
7
|
+
list_pages: {
|
|
8
|
+
description: string;
|
|
9
|
+
inputSchema: z.ZodObject<{
|
|
10
|
+
includeContent: z.ZodOptional<z.ZodBoolean>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
handler: (db: DrizzleDatabase, input: {
|
|
13
|
+
includeContent?: boolean;
|
|
14
|
+
}) => Promise<{
|
|
15
|
+
slug: string;
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
sourceFiles: string | null;
|
|
19
|
+
fieldCount: number | null;
|
|
20
|
+
createdAt: Date;
|
|
21
|
+
updatedAt: Date;
|
|
22
|
+
}[]>;
|
|
23
|
+
};
|
|
24
|
+
get_page: {
|
|
25
|
+
description: string;
|
|
26
|
+
inputSchema: z.ZodObject<{
|
|
27
|
+
slug: z.ZodString;
|
|
28
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
handler: (db: DrizzleDatabase, input: {
|
|
31
|
+
slug: string;
|
|
32
|
+
locale?: string;
|
|
33
|
+
}) => Promise<{
|
|
34
|
+
content: {
|
|
35
|
+
path: string;
|
|
36
|
+
content: import("@reverso/db").Content;
|
|
37
|
+
}[];
|
|
38
|
+
slug: string;
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
sourceFiles: string | null;
|
|
42
|
+
fieldCount: number | null;
|
|
43
|
+
createdAt: Date;
|
|
44
|
+
updatedAt: Date;
|
|
45
|
+
}>;
|
|
46
|
+
};
|
|
47
|
+
get_content: {
|
|
48
|
+
description: string;
|
|
49
|
+
inputSchema: z.ZodObject<{
|
|
50
|
+
path: z.ZodString;
|
|
51
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
52
|
+
}, z.core.$strip>;
|
|
53
|
+
handler: (db: DrizzleDatabase, input: {
|
|
54
|
+
path: string;
|
|
55
|
+
locale?: string;
|
|
56
|
+
}) => Promise<{
|
|
57
|
+
path: string;
|
|
58
|
+
value: null;
|
|
59
|
+
exists: boolean;
|
|
60
|
+
} | {
|
|
61
|
+
exists: boolean;
|
|
62
|
+
locale: string;
|
|
63
|
+
value: string | null;
|
|
64
|
+
id: string;
|
|
65
|
+
createdAt: Date;
|
|
66
|
+
updatedAt: Date;
|
|
67
|
+
fieldId: string;
|
|
68
|
+
published: boolean | null;
|
|
69
|
+
publishedAt: Date | null;
|
|
70
|
+
path?: undefined;
|
|
71
|
+
}>;
|
|
72
|
+
};
|
|
73
|
+
update_content: {
|
|
74
|
+
description: string;
|
|
75
|
+
inputSchema: z.ZodObject<{
|
|
76
|
+
path: z.ZodString;
|
|
77
|
+
value: z.ZodUnknown;
|
|
78
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
79
|
+
changedBy: z.ZodOptional<z.ZodString>;
|
|
80
|
+
}, z.core.$strip>;
|
|
81
|
+
handler: (db: DrizzleDatabase, input: {
|
|
82
|
+
path: string;
|
|
83
|
+
value: unknown;
|
|
84
|
+
locale?: string;
|
|
85
|
+
changedBy?: string;
|
|
86
|
+
}) => Promise<{
|
|
87
|
+
path: string;
|
|
88
|
+
locale: string;
|
|
89
|
+
value: string | null;
|
|
90
|
+
id: string;
|
|
91
|
+
createdAt: Date;
|
|
92
|
+
updatedAt: Date;
|
|
93
|
+
fieldId: string;
|
|
94
|
+
published: boolean | null;
|
|
95
|
+
publishedAt: Date | null;
|
|
96
|
+
}>;
|
|
97
|
+
};
|
|
98
|
+
publish_content: {
|
|
99
|
+
description: string;
|
|
100
|
+
inputSchema: z.ZodObject<{
|
|
101
|
+
path: z.ZodString;
|
|
102
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
103
|
+
}, z.core.$strip>;
|
|
104
|
+
handler: (db: DrizzleDatabase, input: {
|
|
105
|
+
path: string;
|
|
106
|
+
locale?: string;
|
|
107
|
+
}) => Promise<{
|
|
108
|
+
path: string;
|
|
109
|
+
locale: string;
|
|
110
|
+
value: string | null;
|
|
111
|
+
id: string;
|
|
112
|
+
createdAt: Date;
|
|
113
|
+
updatedAt: Date;
|
|
114
|
+
fieldId: string;
|
|
115
|
+
published: boolean | null;
|
|
116
|
+
publishedAt: Date | null;
|
|
117
|
+
}>;
|
|
118
|
+
};
|
|
119
|
+
unpublish_content: {
|
|
120
|
+
description: string;
|
|
121
|
+
inputSchema: z.ZodObject<{
|
|
122
|
+
path: z.ZodString;
|
|
123
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
124
|
+
}, z.core.$strip>;
|
|
125
|
+
handler: (db: DrizzleDatabase, input: {
|
|
126
|
+
path: string;
|
|
127
|
+
locale?: string;
|
|
128
|
+
}) => Promise<{
|
|
129
|
+
path: string;
|
|
130
|
+
locale: string;
|
|
131
|
+
value: string | null;
|
|
132
|
+
id: string;
|
|
133
|
+
createdAt: Date;
|
|
134
|
+
updatedAt: Date;
|
|
135
|
+
fieldId: string;
|
|
136
|
+
published: boolean | null;
|
|
137
|
+
publishedAt: Date | null;
|
|
138
|
+
}>;
|
|
139
|
+
};
|
|
140
|
+
bulk_update_content: {
|
|
141
|
+
description: string;
|
|
142
|
+
inputSchema: z.ZodObject<{
|
|
143
|
+
updates: z.ZodArray<z.ZodObject<{
|
|
144
|
+
path: z.ZodString;
|
|
145
|
+
value: z.ZodUnknown;
|
|
146
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
147
|
+
}, z.core.$strip>>;
|
|
148
|
+
changedBy: z.ZodOptional<z.ZodString>;
|
|
149
|
+
}, z.core.$strip>;
|
|
150
|
+
handler: (db: DrizzleDatabase, input: {
|
|
151
|
+
updates: Array<{
|
|
152
|
+
path: string;
|
|
153
|
+
value: unknown;
|
|
154
|
+
locale?: string;
|
|
155
|
+
}>;
|
|
156
|
+
changedBy?: string;
|
|
157
|
+
}) => Promise<{
|
|
158
|
+
updated: number;
|
|
159
|
+
results: ({
|
|
160
|
+
path: string;
|
|
161
|
+
error: string;
|
|
162
|
+
} | {
|
|
163
|
+
path: string;
|
|
164
|
+
locale: string;
|
|
165
|
+
value: string | null;
|
|
166
|
+
id: string;
|
|
167
|
+
createdAt: Date;
|
|
168
|
+
updatedAt: Date;
|
|
169
|
+
fieldId: string;
|
|
170
|
+
published: boolean | null;
|
|
171
|
+
publishedAt: Date | null;
|
|
172
|
+
error?: undefined;
|
|
173
|
+
})[];
|
|
174
|
+
}>;
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/tools/content.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAanD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,YAAY;;;;;;sBAMD,eAAe,SAAS;YAAE,cAAc,CAAC,EAAE,OAAO,CAAA;SAAE;;;;;;;;;;;;;;;;sBAuBpD,eAAe,SAAS;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;;;;;;;;;;sBAiBzD,eAAe,SAAS;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;;;;;;;;;;;;;;;sBAkBvE,eAAe,SACZ;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;;;;;;;;sBAwB1D,eAAe,SAAS;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;;;;;;;;sBAqBzD,eAAe,SAAS;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;;;;;;;;;;;;sBA4BvE,eAAe,SACZ;YAAE,OAAO,EAAE,KAAK,CAAC;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,OAAO,CAAC;gBAAC,MAAM,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;;;;;;;;;CAsBrG,CAAC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content management tools for the MCP server.
|
|
3
|
+
*/
|
|
4
|
+
import { getPages, getPageBySlug, getContentByPath, getContentByPathPrefix, getFieldByPath, upsertContent, publishContent, unpublishContent, } from '@reverso/db';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export const contentTools = {
|
|
7
|
+
list_pages: {
|
|
8
|
+
description: 'List all pages in the CMS with their sections and field counts',
|
|
9
|
+
inputSchema: z.object({
|
|
10
|
+
includeContent: z.boolean().optional().describe('Include content values in response'),
|
|
11
|
+
}),
|
|
12
|
+
handler: async (db, input) => {
|
|
13
|
+
const pages = await getPages(db);
|
|
14
|
+
if (input.includeContent) {
|
|
15
|
+
const pagesWithContent = await Promise.all(pages.map(async (page) => {
|
|
16
|
+
const content = await getContentByPathPrefix(db, page.slug);
|
|
17
|
+
return { ...page, content };
|
|
18
|
+
}));
|
|
19
|
+
return pagesWithContent;
|
|
20
|
+
}
|
|
21
|
+
return pages;
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
get_page: {
|
|
25
|
+
description: 'Get a specific page by slug with all its sections, fields, and content',
|
|
26
|
+
inputSchema: z.object({
|
|
27
|
+
slug: z.string().describe('The page slug (e.g., "home", "about")'),
|
|
28
|
+
locale: z.string().optional().describe('Locale for content (default: "default")'),
|
|
29
|
+
}),
|
|
30
|
+
handler: async (db, input) => {
|
|
31
|
+
const page = await getPageBySlug(db, input.slug);
|
|
32
|
+
if (!page) {
|
|
33
|
+
throw new Error(`Page not found: ${input.slug}`);
|
|
34
|
+
}
|
|
35
|
+
const content = await getContentByPathPrefix(db, input.slug, input.locale);
|
|
36
|
+
return { ...page, content };
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
get_content: {
|
|
40
|
+
description: 'Get content for a specific field by its path',
|
|
41
|
+
inputSchema: z.object({
|
|
42
|
+
path: z.string().describe('Field path (e.g., "home.hero.title")'),
|
|
43
|
+
locale: z.string().optional().describe('Locale for content (default: "default")'),
|
|
44
|
+
}),
|
|
45
|
+
handler: async (db, input) => {
|
|
46
|
+
const content = await getContentByPath(db, input.path, input.locale);
|
|
47
|
+
if (!content) {
|
|
48
|
+
return { path: input.path, value: null, exists: false };
|
|
49
|
+
}
|
|
50
|
+
return { ...content, exists: true };
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
update_content: {
|
|
54
|
+
description: 'Update content for a specific field',
|
|
55
|
+
inputSchema: z.object({
|
|
56
|
+
path: z.string().describe('Field path (e.g., "home.hero.title")'),
|
|
57
|
+
value: z.unknown().describe('New value for the field'),
|
|
58
|
+
locale: z.string().optional().describe('Locale for content (default: "default")'),
|
|
59
|
+
changedBy: z.string().optional().describe('User or system that made the change'),
|
|
60
|
+
}),
|
|
61
|
+
handler: async (db, input) => {
|
|
62
|
+
// Get the field by path to find its ID
|
|
63
|
+
const field = await getFieldByPath(db, input.path);
|
|
64
|
+
if (!field) {
|
|
65
|
+
throw new Error(`Field not found: ${input.path}`);
|
|
66
|
+
}
|
|
67
|
+
const content = await upsertContent(db, {
|
|
68
|
+
fieldId: field.id,
|
|
69
|
+
value: input.value,
|
|
70
|
+
locale: input.locale ?? 'default',
|
|
71
|
+
changedBy: input.changedBy ?? 'mcp-server',
|
|
72
|
+
});
|
|
73
|
+
return { ...content, path: input.path };
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
publish_content: {
|
|
77
|
+
description: 'Publish content for a specific field, making it live',
|
|
78
|
+
inputSchema: z.object({
|
|
79
|
+
path: z.string().describe('Field path to publish'),
|
|
80
|
+
locale: z.string().optional().describe('Locale for content (default: "default")'),
|
|
81
|
+
}),
|
|
82
|
+
handler: async (db, input) => {
|
|
83
|
+
// Get the content by path to find its ID
|
|
84
|
+
const existingContent = await getContentByPath(db, input.path, input.locale);
|
|
85
|
+
if (!existingContent) {
|
|
86
|
+
throw new Error(`Content not found: ${input.path}`);
|
|
87
|
+
}
|
|
88
|
+
const content = await publishContent(db, existingContent.id);
|
|
89
|
+
if (!content) {
|
|
90
|
+
throw new Error(`Failed to publish content: ${input.path}`);
|
|
91
|
+
}
|
|
92
|
+
return { ...content, path: input.path };
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
unpublish_content: {
|
|
96
|
+
description: 'Unpublish content for a specific field',
|
|
97
|
+
inputSchema: z.object({
|
|
98
|
+
path: z.string().describe('Field path to unpublish'),
|
|
99
|
+
locale: z.string().optional().describe('Locale for content (default: "default")'),
|
|
100
|
+
}),
|
|
101
|
+
handler: async (db, input) => {
|
|
102
|
+
// Get the content by path to find its ID
|
|
103
|
+
const existingContent = await getContentByPath(db, input.path, input.locale);
|
|
104
|
+
if (!existingContent) {
|
|
105
|
+
throw new Error(`Content not found: ${input.path}`);
|
|
106
|
+
}
|
|
107
|
+
const content = await unpublishContent(db, existingContent.id);
|
|
108
|
+
if (!content) {
|
|
109
|
+
throw new Error(`Failed to unpublish content: ${input.path}`);
|
|
110
|
+
}
|
|
111
|
+
return { ...content, path: input.path };
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
bulk_update_content: {
|
|
115
|
+
description: 'Update multiple content fields at once',
|
|
116
|
+
inputSchema: z.object({
|
|
117
|
+
updates: z.array(z.object({
|
|
118
|
+
path: z.string(),
|
|
119
|
+
value: z.unknown(),
|
|
120
|
+
locale: z.string().optional(),
|
|
121
|
+
})).describe('Array of content updates'),
|
|
122
|
+
changedBy: z.string().optional().describe('User or system that made the changes'),
|
|
123
|
+
}),
|
|
124
|
+
handler: async (db, input) => {
|
|
125
|
+
const results = await Promise.all(input.updates.map(async (update) => {
|
|
126
|
+
// Get the field by path to find its ID
|
|
127
|
+
const field = await getFieldByPath(db, update.path);
|
|
128
|
+
if (!field) {
|
|
129
|
+
return { path: update.path, error: `Field not found: ${update.path}` };
|
|
130
|
+
}
|
|
131
|
+
const content = await upsertContent(db, {
|
|
132
|
+
fieldId: field.id,
|
|
133
|
+
value: update.value,
|
|
134
|
+
locale: update.locale ?? 'default',
|
|
135
|
+
changedBy: input.changedBy ?? 'mcp-server',
|
|
136
|
+
});
|
|
137
|
+
return { ...content, path: update.path };
|
|
138
|
+
}));
|
|
139
|
+
return { updated: results.filter(r => !('error' in r)).length, results };
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/tools/content.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forms tools for the MCP server.
|
|
3
|
+
*/
|
|
4
|
+
import type { DrizzleDatabase } from '@reverso/db';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export declare const formsTools: {
|
|
7
|
+
list_forms: {
|
|
8
|
+
description: string;
|
|
9
|
+
inputSchema: z.ZodObject<{
|
|
10
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
11
|
+
published: "published";
|
|
12
|
+
draft: "draft";
|
|
13
|
+
archived: "archived";
|
|
14
|
+
}>>;
|
|
15
|
+
includeFields: z.ZodOptional<z.ZodBoolean>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
handler: (db: DrizzleDatabase, input: {
|
|
18
|
+
status?: string;
|
|
19
|
+
includeFields?: boolean;
|
|
20
|
+
}) => Promise<{
|
|
21
|
+
forms: {
|
|
22
|
+
slug: string;
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
createdAt: Date;
|
|
26
|
+
updatedAt: Date;
|
|
27
|
+
description: string | null;
|
|
28
|
+
status: "published" | "draft" | "archived";
|
|
29
|
+
isMultiStep: boolean | null;
|
|
30
|
+
steps: string | null;
|
|
31
|
+
settings: string | null;
|
|
32
|
+
notifyEmails: string | null;
|
|
33
|
+
notifyOnSubmission: boolean | null;
|
|
34
|
+
webhookUrl: string | null;
|
|
35
|
+
webhookSecret: string | null;
|
|
36
|
+
webhookEnabled: boolean | null;
|
|
37
|
+
honeypotEnabled: boolean | null;
|
|
38
|
+
rateLimitPerMinute: number | null;
|
|
39
|
+
}[];
|
|
40
|
+
total: number;
|
|
41
|
+
}>;
|
|
42
|
+
};
|
|
43
|
+
get_form: {
|
|
44
|
+
description: string;
|
|
45
|
+
inputSchema: z.ZodObject<{
|
|
46
|
+
id: z.ZodOptional<z.ZodString>;
|
|
47
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
handler: (db: DrizzleDatabase, input: {
|
|
50
|
+
id?: string;
|
|
51
|
+
slug?: string;
|
|
52
|
+
}) => Promise<{
|
|
53
|
+
fields: {
|
|
54
|
+
id: string;
|
|
55
|
+
name: string;
|
|
56
|
+
createdAt: Date;
|
|
57
|
+
updatedAt: Date;
|
|
58
|
+
type: string;
|
|
59
|
+
label: string | null;
|
|
60
|
+
placeholder: string | null;
|
|
61
|
+
required: boolean | null;
|
|
62
|
+
validation: string | null;
|
|
63
|
+
condition: string | null;
|
|
64
|
+
config: string | null;
|
|
65
|
+
help: string | null;
|
|
66
|
+
sortOrder: number | null;
|
|
67
|
+
width: number | null;
|
|
68
|
+
formId: string;
|
|
69
|
+
step: number | null;
|
|
70
|
+
}[];
|
|
71
|
+
slug: string;
|
|
72
|
+
id: string;
|
|
73
|
+
name: string;
|
|
74
|
+
createdAt: Date;
|
|
75
|
+
updatedAt: Date;
|
|
76
|
+
description: string | null;
|
|
77
|
+
status: "published" | "draft" | "archived";
|
|
78
|
+
isMultiStep: boolean | null;
|
|
79
|
+
steps: string | null;
|
|
80
|
+
settings: string | null;
|
|
81
|
+
notifyEmails: string | null;
|
|
82
|
+
notifyOnSubmission: boolean | null;
|
|
83
|
+
webhookUrl: string | null;
|
|
84
|
+
webhookSecret: string | null;
|
|
85
|
+
webhookEnabled: boolean | null;
|
|
86
|
+
honeypotEnabled: boolean | null;
|
|
87
|
+
rateLimitPerMinute: number | null;
|
|
88
|
+
}>;
|
|
89
|
+
};
|
|
90
|
+
list_submissions: {
|
|
91
|
+
description: string;
|
|
92
|
+
inputSchema: z.ZodObject<{
|
|
93
|
+
formId: z.ZodString;
|
|
94
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
95
|
+
archived: "archived";
|
|
96
|
+
new: "new";
|
|
97
|
+
read: "read";
|
|
98
|
+
spam: "spam";
|
|
99
|
+
}>>;
|
|
100
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
101
|
+
offset: z.ZodOptional<z.ZodNumber>;
|
|
102
|
+
}, z.core.$strip>;
|
|
103
|
+
handler: (db: DrizzleDatabase, input: {
|
|
104
|
+
formId: string;
|
|
105
|
+
status?: string;
|
|
106
|
+
limit?: number;
|
|
107
|
+
offset?: number;
|
|
108
|
+
}) => Promise<{
|
|
109
|
+
submissions: {
|
|
110
|
+
id: string;
|
|
111
|
+
createdAt: Date;
|
|
112
|
+
data: string;
|
|
113
|
+
status: "archived" | "new" | "read" | "spam";
|
|
114
|
+
formId: string;
|
|
115
|
+
ipAddress: string | null;
|
|
116
|
+
userAgent: string | null;
|
|
117
|
+
referrer: string | null;
|
|
118
|
+
attachments: string | null;
|
|
119
|
+
webhookSentAt: Date | null;
|
|
120
|
+
webhookResponse: string | null;
|
|
121
|
+
}[];
|
|
122
|
+
total: number;
|
|
123
|
+
offset: number;
|
|
124
|
+
limit: number;
|
|
125
|
+
}>;
|
|
126
|
+
};
|
|
127
|
+
get_submission: {
|
|
128
|
+
description: string;
|
|
129
|
+
inputSchema: z.ZodObject<{
|
|
130
|
+
id: z.ZodString;
|
|
131
|
+
}, z.core.$strip>;
|
|
132
|
+
handler: (db: DrizzleDatabase, input: {
|
|
133
|
+
id: string;
|
|
134
|
+
}) => Promise<{
|
|
135
|
+
id: string;
|
|
136
|
+
createdAt: Date;
|
|
137
|
+
data: string;
|
|
138
|
+
status: "archived" | "new" | "read" | "spam";
|
|
139
|
+
formId: string;
|
|
140
|
+
ipAddress: string | null;
|
|
141
|
+
userAgent: string | null;
|
|
142
|
+
referrer: string | null;
|
|
143
|
+
attachments: string | null;
|
|
144
|
+
webhookSentAt: Date | null;
|
|
145
|
+
webhookResponse: string | null;
|
|
146
|
+
}>;
|
|
147
|
+
};
|
|
148
|
+
update_submission_status: {
|
|
149
|
+
description: string;
|
|
150
|
+
inputSchema: z.ZodObject<{
|
|
151
|
+
id: z.ZodString;
|
|
152
|
+
status: z.ZodEnum<{
|
|
153
|
+
archived: "archived";
|
|
154
|
+
new: "new";
|
|
155
|
+
read: "read";
|
|
156
|
+
spam: "spam";
|
|
157
|
+
}>;
|
|
158
|
+
}, z.core.$strip>;
|
|
159
|
+
handler: (db: DrizzleDatabase, input: {
|
|
160
|
+
id: string;
|
|
161
|
+
status: "new" | "read" | "spam" | "archived";
|
|
162
|
+
}) => Promise<{
|
|
163
|
+
id: string;
|
|
164
|
+
createdAt: Date;
|
|
165
|
+
data: string;
|
|
166
|
+
status: "archived" | "new" | "read" | "spam";
|
|
167
|
+
formId: string;
|
|
168
|
+
ipAddress: string | null;
|
|
169
|
+
userAgent: string | null;
|
|
170
|
+
referrer: string | null;
|
|
171
|
+
attachments: string | null;
|
|
172
|
+
webhookSentAt: Date | null;
|
|
173
|
+
webhookResponse: string | null;
|
|
174
|
+
}>;
|
|
175
|
+
};
|
|
176
|
+
get_form_stats: {
|
|
177
|
+
description: string;
|
|
178
|
+
inputSchema: z.ZodObject<{
|
|
179
|
+
formId: z.ZodString;
|
|
180
|
+
}, z.core.$strip>;
|
|
181
|
+
handler: (db: DrizzleDatabase, input: {
|
|
182
|
+
formId: string;
|
|
183
|
+
}) => Promise<{
|
|
184
|
+
form: {
|
|
185
|
+
id: string;
|
|
186
|
+
name: string;
|
|
187
|
+
slug: string;
|
|
188
|
+
status: "published" | "draft" | "archived";
|
|
189
|
+
};
|
|
190
|
+
totalSubmissions: number;
|
|
191
|
+
byStatus: Record<string, number>;
|
|
192
|
+
recentSubmissions: number;
|
|
193
|
+
fieldCount: number;
|
|
194
|
+
}>;
|
|
195
|
+
};
|
|
196
|
+
};
|
|
197
|
+
//# sourceMappingURL=forms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forms.d.ts","sourceRoot":"","sources":["../../src/tools/forms.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAYnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,UAAU;;;;;;;;;;;sBAQb,eAAe,SACZ;YAAE,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,aAAa,CAAC,EAAE,OAAO,CAAA;SAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBA4BjC,eAAe,SAAS;YAAE,EAAE,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBA8BpE,eAAe,SACZ;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;;;;;;;;;;;;;;sBAuBzD,eAAe,SAAS;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;;;;;;;;;;;;;;;sBAetC,eAAe,SAAS;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAA;SAAE;;;;;;;;;;;;;;;;;;;sBAcpF,eAAe,SAAS;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;;;CAkCjE,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forms tools for the MCP server.
|
|
3
|
+
*/
|
|
4
|
+
import { getForms, getFormById, getFormBySlug, getFormFields, getFormSubmissions, getFormSubmissionById, updateFormSubmissionStatus, } from '@reverso/db';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export const formsTools = {
|
|
7
|
+
list_forms: {
|
|
8
|
+
description: 'List all forms in the CMS',
|
|
9
|
+
inputSchema: z.object({
|
|
10
|
+
status: z.enum(['draft', 'published', 'archived']).optional().describe('Filter by form status'),
|
|
11
|
+
includeFields: z.boolean().optional().describe('Include form fields in response'),
|
|
12
|
+
}),
|
|
13
|
+
handler: async (db, input) => {
|
|
14
|
+
let forms = await getForms(db);
|
|
15
|
+
if (input.status) {
|
|
16
|
+
forms = forms.filter((f) => f.status === input.status);
|
|
17
|
+
}
|
|
18
|
+
if (input.includeFields) {
|
|
19
|
+
const formsWithFields = await Promise.all(forms.map(async (form) => {
|
|
20
|
+
const fields = await getFormFields(db, form.id);
|
|
21
|
+
return { ...form, fields };
|
|
22
|
+
}));
|
|
23
|
+
return { forms: formsWithFields, total: formsWithFields.length };
|
|
24
|
+
}
|
|
25
|
+
return { forms, total: forms.length };
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
get_form: {
|
|
29
|
+
description: 'Get a specific form by ID or slug with all its fields',
|
|
30
|
+
inputSchema: z.object({
|
|
31
|
+
id: z.string().optional().describe('Form ID'),
|
|
32
|
+
slug: z.string().optional().describe('Form slug'),
|
|
33
|
+
}),
|
|
34
|
+
handler: async (db, input) => {
|
|
35
|
+
if (!input.id && !input.slug) {
|
|
36
|
+
throw new Error('Either id or slug must be provided');
|
|
37
|
+
}
|
|
38
|
+
let form = null;
|
|
39
|
+
if (input.id) {
|
|
40
|
+
form = await getFormById(db, input.id);
|
|
41
|
+
}
|
|
42
|
+
else if (input.slug) {
|
|
43
|
+
form = await getFormBySlug(db, input.slug);
|
|
44
|
+
}
|
|
45
|
+
if (!form) {
|
|
46
|
+
throw new Error(`Form not found: ${input.id ?? input.slug}`);
|
|
47
|
+
}
|
|
48
|
+
const fields = await getFormFields(db, form.id);
|
|
49
|
+
return { ...form, fields };
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
list_submissions: {
|
|
53
|
+
description: 'List submissions for a specific form',
|
|
54
|
+
inputSchema: z.object({
|
|
55
|
+
formId: z.string().describe('Form ID'),
|
|
56
|
+
status: z.enum(['new', 'read', 'spam', 'archived']).optional().describe('Filter by submission status'),
|
|
57
|
+
limit: z.number().optional().describe('Maximum number of results'),
|
|
58
|
+
offset: z.number().optional().describe('Offset for pagination'),
|
|
59
|
+
}),
|
|
60
|
+
handler: async (db, input) => {
|
|
61
|
+
let submissions = await getFormSubmissions(db, { formId: input.formId });
|
|
62
|
+
if (input.status) {
|
|
63
|
+
submissions = submissions.filter((s) => s.status === input.status);
|
|
64
|
+
}
|
|
65
|
+
const total = submissions.length;
|
|
66
|
+
const offset = input.offset ?? 0;
|
|
67
|
+
const limit = input.limit ?? 50;
|
|
68
|
+
submissions = submissions.slice(offset, offset + limit);
|
|
69
|
+
return { submissions, total, offset, limit };
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
get_submission: {
|
|
73
|
+
description: 'Get a specific form submission by ID',
|
|
74
|
+
inputSchema: z.object({
|
|
75
|
+
id: z.string().describe('Submission ID'),
|
|
76
|
+
}),
|
|
77
|
+
handler: async (db, input) => {
|
|
78
|
+
const submission = await getFormSubmissionById(db, input.id);
|
|
79
|
+
if (!submission) {
|
|
80
|
+
throw new Error(`Submission not found: ${input.id}`);
|
|
81
|
+
}
|
|
82
|
+
return submission;
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
update_submission_status: {
|
|
86
|
+
description: 'Update the status of a form submission',
|
|
87
|
+
inputSchema: z.object({
|
|
88
|
+
id: z.string().describe('Submission ID'),
|
|
89
|
+
status: z.enum(['new', 'read', 'spam', 'archived']).describe('New status'),
|
|
90
|
+
}),
|
|
91
|
+
handler: async (db, input) => {
|
|
92
|
+
const submission = await updateFormSubmissionStatus(db, input.id, input.status);
|
|
93
|
+
if (!submission) {
|
|
94
|
+
throw new Error(`Submission not found: ${input.id}`);
|
|
95
|
+
}
|
|
96
|
+
return submission;
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
get_form_stats: {
|
|
100
|
+
description: 'Get statistics for a specific form',
|
|
101
|
+
inputSchema: z.object({
|
|
102
|
+
formId: z.string().describe('Form ID'),
|
|
103
|
+
}),
|
|
104
|
+
handler: async (db, input) => {
|
|
105
|
+
const form = await getFormById(db, input.formId);
|
|
106
|
+
if (!form) {
|
|
107
|
+
throw new Error(`Form not found: ${input.formId}`);
|
|
108
|
+
}
|
|
109
|
+
const submissions = await getFormSubmissions(db, { formId: input.formId });
|
|
110
|
+
const fields = await getFormFields(db, input.formId);
|
|
111
|
+
const byStatus = submissions.reduce((acc, s) => {
|
|
112
|
+
acc[s.status] = (acc[s.status] ?? 0) + 1;
|
|
113
|
+
return acc;
|
|
114
|
+
}, {});
|
|
115
|
+
// Get submissions per day (last 30 days)
|
|
116
|
+
const now = Date.now();
|
|
117
|
+
const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1000;
|
|
118
|
+
const recentSubmissions = submissions.filter((s) => {
|
|
119
|
+
const createdAt = new Date(s.createdAt).getTime();
|
|
120
|
+
return createdAt >= thirtyDaysAgo;
|
|
121
|
+
});
|
|
122
|
+
return {
|
|
123
|
+
form: { id: form.id, name: form.name, slug: form.slug, status: form.status },
|
|
124
|
+
totalSubmissions: submissions.length,
|
|
125
|
+
byStatus,
|
|
126
|
+
recentSubmissions: recentSubmissions.length,
|
|
127
|
+
fieldCount: fields.length,
|
|
128
|
+
};
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
//# sourceMappingURL=forms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forms.js","sourceRoot":"","sources":["../../src/tools/forms.ts"],"names":[],"mappings":"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"}
|