@wplaunchify/ml-mcp-server 2.1.4 → 2.4.4

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.
@@ -11,6 +11,7 @@ import { fluentCommunityLayoutTools, fluentCommunityLayoutHandlers } from './flu
11
11
  import { fluentCartTools, fluentCartHandlers } from './fluent-cart.js';
12
12
  import { fluentCRMTools, fluentCRMHandlers } from './fluent-crm.js';
13
13
  import { mlCanvasTools, mlCanvasHandlers } from './ml-canvas.js';
14
+ import { mlSimpleSiteTools, mlSimpleSiteHandlers } from './ml-simple-site.js';
14
15
  import { mlImageEditorTools, mlImageEditorHandlers } from './ml-image-editor.js';
15
16
  import { fluentAffiliateTools, fluentAffiliateHandlers } from './fluent-affiliate.js';
16
17
  import { mlMediaHubTools, mlMediaHubHandlers } from './ml-media-hub.js';
@@ -32,7 +33,8 @@ const toolCategories = {
32
33
  ...userTools,
33
34
  ...pluginRepositoryTools,
34
35
  ...commentTools,
35
- ...mlCanvasTools
36
+ ...mlCanvasTools,
37
+ ...mlSimpleSiteTools
36
38
  ],
37
39
  // Full FluentCommunity (91 tools) - legacy support
38
40
  fluentcommunity: [
@@ -74,7 +76,7 @@ const toolCategories = {
74
76
  ]
75
77
  };
76
78
  const handlerCategories = {
77
- // WP (ENABLED_TOOLS=wordpress) - 40 tools
79
+ // WP (ENABLED_TOOLS=wordpress) - 45 tools
78
80
  wordpress: {
79
81
  ...unifiedContentHandlers,
80
82
  ...unifiedTaxonomyHandlers,
@@ -83,7 +85,8 @@ const handlerCategories = {
83
85
  ...userHandlers,
84
86
  ...pluginRepositoryHandlers,
85
87
  ...commentHandlers,
86
- ...mlCanvasHandlers // ML Canvas is part of WordPress category
88
+ ...mlCanvasHandlers, // ML Canvas is part of WordPress category
89
+ ...mlSimpleSiteHandlers // ML Simple Site tools
87
90
  },
88
91
  fluentcommunity: {
89
92
  ...fluentCommunityHandlers,
@@ -61,6 +61,25 @@ declare const deleteMediaSchema: z.ZodObject<{
61
61
  id: number;
62
62
  force?: boolean | undefined;
63
63
  }>;
64
+ declare const uploadMediaSchema: z.ZodObject<{
65
+ file_path: z.ZodString;
66
+ title: z.ZodOptional<z.ZodString>;
67
+ alt_text: z.ZodOptional<z.ZodString>;
68
+ caption: z.ZodOptional<z.ZodString>;
69
+ description: z.ZodOptional<z.ZodString>;
70
+ }, "strict", z.ZodTypeAny, {
71
+ file_path: string;
72
+ title?: string | undefined;
73
+ description?: string | undefined;
74
+ alt_text?: string | undefined;
75
+ caption?: string | undefined;
76
+ }, {
77
+ file_path: string;
78
+ title?: string | undefined;
79
+ description?: string | undefined;
80
+ alt_text?: string | undefined;
81
+ caption?: string | undefined;
82
+ }>;
64
83
  export declare const mediaTools: Tool[];
65
84
  export declare const mediaHandlers: {
66
85
  list_media: (params: z.infer<typeof listMediaSchema>) => Promise<{
@@ -97,6 +116,23 @@ export declare const mediaHandlers: {
97
116
  }[];
98
117
  };
99
118
  }>;
119
+ upload_media: (params: z.infer<typeof uploadMediaSchema>) => Promise<{
120
+ toolResult: {
121
+ isError: boolean;
122
+ content: {
123
+ type: string;
124
+ text: string;
125
+ }[];
126
+ };
127
+ } | {
128
+ toolResult: {
129
+ content: {
130
+ type: string;
131
+ text: string;
132
+ }[];
133
+ isError?: undefined;
134
+ };
135
+ }>;
100
136
  edit_media: (params: z.infer<typeof editMediaSchema>) => Promise<{
101
137
  toolResult: {
102
138
  content: {
@@ -27,6 +27,14 @@ const deleteMediaSchema = z.object({
27
27
  id: z.number().describe("Media ID to delete"),
28
28
  force: z.boolean().optional().describe("Force deletion bypassing trash")
29
29
  }).strict();
30
+ // Schema for uploading a local file to WordPress media library
31
+ const uploadMediaSchema = z.object({
32
+ file_path: z.string().describe("Local file path to upload"),
33
+ title: z.string().optional().describe("Media title"),
34
+ alt_text: z.string().optional().describe("Alternate text for the media"),
35
+ caption: z.string().optional().describe("Caption of the media"),
36
+ description: z.string().optional().describe("Description of the media")
37
+ }).strict();
30
38
  // Define the tool set for media operations
31
39
  export const mediaTools = [
32
40
  {
@@ -39,6 +47,11 @@ export const mediaTools = [
39
47
  description: "Creates a new media item",
40
48
  inputSchema: { type: "object", properties: createMediaSchema.shape }
41
49
  },
50
+ {
51
+ name: "upload_media",
52
+ description: "Uploads a local file to WordPress media library",
53
+ inputSchema: { type: "object", properties: uploadMediaSchema.shape }
54
+ },
42
55
  {
43
56
  name: "edit_media",
44
57
  description: "Updates an existing media item",
@@ -125,6 +138,61 @@ export const mediaHandlers = {
125
138
  };
126
139
  }
127
140
  },
141
+ upload_media: async (params) => {
142
+ try {
143
+ const fs = await import('fs');
144
+ const path = await import('path');
145
+ const axios = (await import('axios')).default;
146
+ const FormData = (await import('form-data')).default;
147
+ // Check if file exists
148
+ if (!fs.existsSync(params.file_path)) {
149
+ return {
150
+ toolResult: {
151
+ isError: true,
152
+ content: [{ type: "text", text: `File not found: ${params.file_path}` }]
153
+ }
154
+ };
155
+ }
156
+ // Read the file
157
+ const fileBuffer = fs.readFileSync(params.file_path);
158
+ const fileName = path.basename(params.file_path);
159
+ // Create form data
160
+ const form = new FormData();
161
+ form.append('file', fileBuffer, {
162
+ filename: fileName,
163
+ contentType: 'application/octet-stream'
164
+ });
165
+ // Append additional fields if provided
166
+ if (params.title)
167
+ form.append('title', params.title);
168
+ if (params.alt_text)
169
+ form.append('alt_text', params.alt_text);
170
+ if (params.caption)
171
+ form.append('caption', params.caption);
172
+ if (params.description)
173
+ form.append('description', params.description);
174
+ // Upload to WordPress via our custom endpoint
175
+ const response = await makeWordPressRequest('POST', 'fc-manager/v1/wordpress/media/upload', form, {
176
+ isFormData: true,
177
+ headers: form.getHeaders(),
178
+ rawResponse: true
179
+ });
180
+ return {
181
+ toolResult: {
182
+ content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }]
183
+ }
184
+ };
185
+ }
186
+ catch (error) {
187
+ const errorMessage = error.response?.data?.message || error.message;
188
+ return {
189
+ toolResult: {
190
+ isError: true,
191
+ content: [{ type: "text", text: `Error uploading media: ${errorMessage}` }]
192
+ }
193
+ };
194
+ }
195
+ },
128
196
  edit_media: async (params) => {
129
197
  try {
130
198
  const { id, ...updateData } = params;
@@ -0,0 +1,196 @@
1
+ import { z } from 'zod';
2
+ export declare const mlSimpleSiteTools: ({
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ type: "object";
7
+ properties: {};
8
+ };
9
+ } | {
10
+ name: string;
11
+ description: string;
12
+ inputSchema: {
13
+ type: "object";
14
+ properties: {
15
+ settings: z.ZodObject<{
16
+ site_mode: z.ZodOptional<z.ZodEnum<["single", "multi"]>>;
17
+ site_title: z.ZodOptional<z.ZodString>;
18
+ logo_url: z.ZodOptional<z.ZodString>;
19
+ primary_color: z.ZodOptional<z.ZodString>;
20
+ display_location: z.ZodOptional<z.ZodEnum<["disabled", "homepage", "page"]>>;
21
+ display_page_id: z.ZodOptional<z.ZodNumber>;
22
+ show_header: z.ZodOptional<z.ZodEnum<["yes", "no"]>>;
23
+ nav_style: z.ZodOptional<z.ZodEnum<["fixed", "static"]>>;
24
+ header_height: z.ZodOptional<z.ZodNumber>;
25
+ header_bg: z.ZodOptional<z.ZodString>;
26
+ nav_link_color: z.ZodOptional<z.ZodString>;
27
+ nav_font: z.ZodOptional<z.ZodString>;
28
+ nav_font_size: z.ZodOptional<z.ZodNumber>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ logo_url?: string | undefined;
31
+ site_title?: string | undefined;
32
+ site_mode?: "single" | "multi" | undefined;
33
+ primary_color?: string | undefined;
34
+ display_location?: "page" | "disabled" | "homepage" | undefined;
35
+ display_page_id?: number | undefined;
36
+ show_header?: "yes" | "no" | undefined;
37
+ nav_style?: "fixed" | "static" | undefined;
38
+ header_height?: number | undefined;
39
+ header_bg?: string | undefined;
40
+ nav_link_color?: string | undefined;
41
+ nav_font?: string | undefined;
42
+ nav_font_size?: number | undefined;
43
+ }, {
44
+ logo_url?: string | undefined;
45
+ site_title?: string | undefined;
46
+ site_mode?: "single" | "multi" | undefined;
47
+ primary_color?: string | undefined;
48
+ display_location?: "page" | "disabled" | "homepage" | undefined;
49
+ display_page_id?: number | undefined;
50
+ show_header?: "yes" | "no" | undefined;
51
+ nav_style?: "fixed" | "static" | undefined;
52
+ header_height?: number | undefined;
53
+ header_bg?: string | undefined;
54
+ nav_link_color?: string | undefined;
55
+ nav_font?: string | undefined;
56
+ nav_font_size?: number | undefined;
57
+ }>;
58
+ blocks: z.ZodArray<z.ZodObject<{
59
+ name: z.ZodString;
60
+ html: z.ZodString;
61
+ css: z.ZodOptional<z.ZodString>;
62
+ hide_from_nav: z.ZodOptional<z.ZodBoolean>;
63
+ }, "strip", z.ZodTypeAny, {
64
+ name: string;
65
+ html: string;
66
+ css?: string | undefined;
67
+ hide_from_nav?: boolean | undefined;
68
+ }, {
69
+ name: string;
70
+ html: string;
71
+ css?: string | undefined;
72
+ hide_from_nav?: boolean | undefined;
73
+ }>, "many">;
74
+ };
75
+ };
76
+ } | {
77
+ name: string;
78
+ description: string;
79
+ inputSchema: {
80
+ type: "object";
81
+ properties: {
82
+ site_mode: z.ZodOptional<z.ZodEnum<["single", "multi"]>>;
83
+ site_title: z.ZodOptional<z.ZodString>;
84
+ logo_url: z.ZodOptional<z.ZodString>;
85
+ primary_color: z.ZodOptional<z.ZodString>;
86
+ display_location: z.ZodOptional<z.ZodEnum<["disabled", "homepage", "page"]>>;
87
+ display_page_id: z.ZodOptional<z.ZodNumber>;
88
+ show_header: z.ZodOptional<z.ZodEnum<["yes", "no"]>>;
89
+ nav_style: z.ZodOptional<z.ZodEnum<["fixed", "static"]>>;
90
+ header_height: z.ZodOptional<z.ZodNumber>;
91
+ header_bg: z.ZodOptional<z.ZodString>;
92
+ nav_link_color: z.ZodOptional<z.ZodString>;
93
+ nav_font: z.ZodOptional<z.ZodString>;
94
+ nav_font_size: z.ZodOptional<z.ZodNumber>;
95
+ };
96
+ };
97
+ } | {
98
+ name: string;
99
+ description: string;
100
+ inputSchema: {
101
+ type: "object";
102
+ properties: {
103
+ name: z.ZodString;
104
+ html: z.ZodString;
105
+ css: z.ZodOptional<z.ZodString>;
106
+ hide_from_nav: z.ZodOptional<z.ZodBoolean>;
107
+ };
108
+ };
109
+ })[];
110
+ export declare const mlSimpleSiteHandlers: {
111
+ mlss_get_site: (args: any) => Promise<{
112
+ toolResult: {
113
+ content: {
114
+ type: string;
115
+ text: string;
116
+ }[];
117
+ isError?: undefined;
118
+ };
119
+ } | {
120
+ toolResult: {
121
+ isError: boolean;
122
+ content: {
123
+ type: string;
124
+ text: string;
125
+ }[];
126
+ };
127
+ }>;
128
+ mlss_save_site: (args: any) => Promise<{
129
+ toolResult: {
130
+ content: {
131
+ type: string;
132
+ text: string;
133
+ }[];
134
+ isError?: undefined;
135
+ };
136
+ } | {
137
+ toolResult: {
138
+ isError: boolean;
139
+ content: {
140
+ type: string;
141
+ text: string;
142
+ }[];
143
+ };
144
+ }>;
145
+ mlss_update_settings: (args: any) => Promise<{
146
+ toolResult: {
147
+ content: {
148
+ type: string;
149
+ text: string;
150
+ }[];
151
+ isError?: undefined;
152
+ };
153
+ } | {
154
+ toolResult: {
155
+ isError: boolean;
156
+ content: {
157
+ type: string;
158
+ text: string;
159
+ }[];
160
+ };
161
+ }>;
162
+ mlss_add_block: (args: any) => Promise<{
163
+ toolResult: {
164
+ content: {
165
+ type: string;
166
+ text: string;
167
+ }[];
168
+ isError?: undefined;
169
+ };
170
+ } | {
171
+ toolResult: {
172
+ isError: boolean;
173
+ content: {
174
+ type: string;
175
+ text: string;
176
+ }[];
177
+ };
178
+ }>;
179
+ mlss_get_preview_url: (args: any) => Promise<{
180
+ toolResult: {
181
+ content: {
182
+ type: string;
183
+ text: string;
184
+ }[];
185
+ isError?: undefined;
186
+ };
187
+ } | {
188
+ toolResult: {
189
+ isError: boolean;
190
+ content: {
191
+ type: string;
192
+ text: string;
193
+ }[];
194
+ };
195
+ }>;
196
+ };
@@ -0,0 +1,194 @@
1
+ import { z } from 'zod';
2
+ import { makeWordPressRequest } from '../wordpress.js';
3
+ // ML Simple Site Tools - Complete Website Creation via MCP
4
+ // Requires ML Simple Site plugin v1.6.0+ on WordPress
5
+ export const mlSimpleSiteTools = [
6
+ {
7
+ name: 'mlss_get_site',
8
+ description: 'Get the complete ML Simple Site configuration including settings, blocks, and preview URL',
9
+ inputSchema: { type: 'object', properties: {} },
10
+ },
11
+ {
12
+ name: 'mlss_save_site',
13
+ description: 'Save complete ML Simple Site - settings and all blocks at once. Use this to create or replace an entire site. Perfect for generating personalized websites from CRM contact data.',
14
+ inputSchema: { type: 'object', properties: z.object({
15
+ settings: z.object({
16
+ site_mode: z.enum(['single', 'multi']).optional().describe('single=scroll page, multi=separate pages'),
17
+ site_title: z.string().optional().describe('Site title displayed in header'),
18
+ logo_url: z.string().optional().describe('URL to logo image'),
19
+ primary_color: z.string().optional().describe('Hex color like #2563eb'),
20
+ display_location: z.enum(['disabled', 'homepage', 'page']).optional().describe('Where to display the site'),
21
+ display_page_id: z.number().optional().describe('Page ID when display_location is page'),
22
+ show_header: z.enum(['yes', 'no']).optional().describe('Show site header'),
23
+ nav_style: z.enum(['fixed', 'static']).optional().describe('Navigation style'),
24
+ header_height: z.number().optional().describe('Header height in pixels'),
25
+ header_bg: z.string().optional().describe('Header background color (hex)'),
26
+ nav_link_color: z.string().optional().describe('Navigation link color (hex)'),
27
+ nav_font: z.string().optional().describe('Navigation font family'),
28
+ nav_font_size: z.number().optional().describe('Navigation font size in pixels'),
29
+ }).describe('Site settings object'),
30
+ blocks: z.array(z.object({
31
+ name: z.string().describe('Block name (appears in nav)'),
32
+ html: z.string().describe('HTML content'),
33
+ css: z.string().optional().describe('CSS styles'),
34
+ hide_from_nav: z.boolean().optional().describe('Hide from navigation menu'),
35
+ })).describe('Array of content blocks'),
36
+ }).shape },
37
+ },
38
+ {
39
+ name: 'mlss_update_settings',
40
+ description: 'Update ML Simple Site settings. Supports partial updates - only specify fields you want to change.',
41
+ inputSchema: { type: 'object', properties: z.object({
42
+ site_mode: z.enum(['single', 'multi']).optional().describe('single=scroll page, multi=separate pages'),
43
+ site_title: z.string().optional().describe('Site title displayed in header'),
44
+ logo_url: z.string().optional().describe('URL to logo image'),
45
+ primary_color: z.string().optional().describe('Hex color like #FF6B35'),
46
+ display_location: z.enum(['disabled', 'homepage', 'page']).optional().describe('Where to display the site'),
47
+ display_page_id: z.number().optional().describe('Page ID when display_location is page'),
48
+ show_header: z.enum(['yes', 'no']).optional().describe('Show site header'),
49
+ nav_style: z.enum(['fixed', 'static']).optional().describe('Navigation style'),
50
+ header_height: z.number().optional().describe('Header height in pixels'),
51
+ header_bg: z.string().optional().describe('Header background color (hex)'),
52
+ nav_link_color: z.string().optional().describe('Navigation link color (hex)'),
53
+ nav_font: z.string().optional().describe('Navigation font family'),
54
+ nav_font_size: z.number().optional().describe('Navigation font size in pixels'),
55
+ }).shape },
56
+ },
57
+ {
58
+ name: 'mlss_add_block',
59
+ description: 'Add a single content block to ML Simple Site. Block is appended to the end.',
60
+ inputSchema: { type: 'object', properties: z.object({
61
+ name: z.string().describe('Block name (appears in navigation)'),
62
+ html: z.string().describe('HTML content for the block'),
63
+ css: z.string().optional().describe('CSS styles for the block'),
64
+ hide_from_nav: z.boolean().optional().describe('Hide from navigation menu (default false)'),
65
+ }).shape },
66
+ },
67
+ {
68
+ name: 'mlss_get_preview_url',
69
+ description: 'Get the frontend preview URL for the ML Simple Site',
70
+ inputSchema: { type: 'object', properties: {} },
71
+ },
72
+ ];
73
+ export const mlSimpleSiteHandlers = {
74
+ mlss_get_site: async (args) => {
75
+ try {
76
+ const response = await makeWordPressRequest('GET', 'mlss/v1/site');
77
+ return {
78
+ toolResult: {
79
+ content: [{
80
+ type: 'text',
81
+ text: JSON.stringify(response, null, 2)
82
+ }]
83
+ }
84
+ };
85
+ }
86
+ catch (error) {
87
+ return {
88
+ toolResult: {
89
+ isError: true,
90
+ content: [{
91
+ type: 'text',
92
+ text: `Error getting site: ${error.message}`
93
+ }]
94
+ }
95
+ };
96
+ }
97
+ },
98
+ mlss_save_site: async (args) => {
99
+ try {
100
+ const response = await makeWordPressRequest('POST', 'mlss/v1/site', args);
101
+ return {
102
+ toolResult: {
103
+ content: [{
104
+ type: 'text',
105
+ text: JSON.stringify(response, null, 2)
106
+ }]
107
+ }
108
+ };
109
+ }
110
+ catch (error) {
111
+ return {
112
+ toolResult: {
113
+ isError: true,
114
+ content: [{
115
+ type: 'text',
116
+ text: `Error saving site: ${error.message}`
117
+ }]
118
+ }
119
+ };
120
+ }
121
+ },
122
+ mlss_update_settings: async (args) => {
123
+ try {
124
+ const response = await makeWordPressRequest('POST', 'mlss/v1/settings', args);
125
+ return {
126
+ toolResult: {
127
+ content: [{
128
+ type: 'text',
129
+ text: JSON.stringify(response, null, 2)
130
+ }]
131
+ }
132
+ };
133
+ }
134
+ catch (error) {
135
+ return {
136
+ toolResult: {
137
+ isError: true,
138
+ content: [{
139
+ type: 'text',
140
+ text: `Error updating settings: ${error.message}`
141
+ }]
142
+ }
143
+ };
144
+ }
145
+ },
146
+ mlss_add_block: async (args) => {
147
+ try {
148
+ const response = await makeWordPressRequest('POST', 'mlss/v1/blocks/add', args);
149
+ return {
150
+ toolResult: {
151
+ content: [{
152
+ type: 'text',
153
+ text: JSON.stringify(response, null, 2)
154
+ }]
155
+ }
156
+ };
157
+ }
158
+ catch (error) {
159
+ return {
160
+ toolResult: {
161
+ isError: true,
162
+ content: [{
163
+ type: 'text',
164
+ text: `Error adding block: ${error.message}`
165
+ }]
166
+ }
167
+ };
168
+ }
169
+ },
170
+ mlss_get_preview_url: async (args) => {
171
+ try {
172
+ const response = await makeWordPressRequest('GET', 'mlss/v1/preview-url');
173
+ return {
174
+ toolResult: {
175
+ content: [{
176
+ type: 'text',
177
+ text: JSON.stringify(response, null, 2)
178
+ }]
179
+ }
180
+ };
181
+ }
182
+ catch (error) {
183
+ return {
184
+ toolResult: {
185
+ isError: true,
186
+ content: [{
187
+ type: 'text',
188
+ text: `Error getting preview URL: ${error.message}`
189
+ }]
190
+ }
191
+ };
192
+ }
193
+ },
194
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wplaunchify/ml-mcp-server",
3
- "version": "2.1.4",
3
+ "version": "2.4.4",
4
4
  "description": "Universal MCP Server for WordPress + Fluent Suite (Community, CRM, Cart) + MinuteLaunch Plugins. Comprehensive tools for AI-powered WordPress management via Claude, Cursor, and other MCP clients.",
5
5
  "type": "module",
6
6
  "main": "./build/server.js",