@wix/mcp 1.0.92 → 1.0.94

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.
Files changed (38) hide show
  1. package/build/bin-standalone.js +180 -212
  2. package/build/cjs/index.cjs +757 -216
  3. package/build/cjs/toolkit.cjs +725 -209
  4. package/build/dts/api-call/index.js +6 -3
  5. package/build/dts/api-call/site-files.d.ts +28 -0
  6. package/build/dts/api-call/site-files.js +194 -0
  7. package/build/dts/api-call/upload-headless-website-files.d.ts +35 -0
  8. package/build/dts/api-call/upload-headless-website-files.js +171 -0
  9. package/build/dts/bin.js +3 -6
  10. package/build/dts/code-mode/attachments.d.ts +37 -0
  11. package/build/dts/code-mode/attachments.js +218 -0
  12. package/build/dts/code-mode/index.js +53 -6
  13. package/build/dts/config/default-config.d.ts +0 -4
  14. package/build/dts/config/default-config.js +48 -56
  15. package/build/dts/config/param-descriptions.js +5 -5
  16. package/build/dts/docs/docs.d.ts +4 -2
  17. package/build/dts/docs/docs.js +25 -15
  18. package/build/dts/docs/fetch-article.js +4 -1
  19. package/build/dts/docs/get-to-know.js +1 -1
  20. package/build/dts/docs/semanticSearch.d.ts +2 -1
  21. package/build/dts/docs/semanticSearch.js +12 -5
  22. package/build/dts/docs/start-headless-build.d.ts +19 -0
  23. package/build/dts/docs/start-headless-build.js +74 -0
  24. package/build/dts/graphql/index.js +3 -1
  25. package/build/dts/import-claude-design-tool/index.js +2 -2
  26. package/build/dts/index.d.ts +1 -0
  27. package/build/dts/index.js +1 -0
  28. package/build/dts/site-widget-tools/search-site-templates-tool/index.js +17 -7
  29. package/build/dts/toolkit-entry.d.cts +4 -2
  30. package/build/dts/toolkit-entry.d.ts +4 -2
  31. package/build/dts/toolkit.js +9 -0
  32. package/build/dts/wix-mcp-server.d.ts +2 -0
  33. package/build/dts/wix-mcp-server.js +4 -0
  34. package/build/esm/index.js +755 -216
  35. package/build/esm/toolkit.js +725 -209
  36. package/package.json +2 -2
  37. package/build/dts/docs/create-site-guide.d.ts +0 -3
  38. package/build/dts/docs/create-site-guide.js +0 -109
@@ -0,0 +1,74 @@
1
+ import { z } from 'zod';
2
+ import { defaultToolDescriptions } from '../config/default-config.js';
3
+ import { fetchArticleContent } from './fetch-article.js';
4
+ import { START_DEPLOY_WEBSITE_PARAM_DESCRIPTIONS } from './start-deploy-website.js';
5
+ export const START_HEADLESS_BUILD_TOOL_NAME = 'StartHeadlessBuild';
6
+ /** Wix's headless guide; identical to https://www.wix.com/headless/skill.md. */
7
+ export const HEADLESS_GUIDE_URL = 'https://www.wix.com/skills/headless-cold-start/headless-kit.md';
8
+ export const START_HEADLESS_BUILD_STARTING_POINTS = [
9
+ 'nothing yet',
10
+ 'a design worked out in this conversation',
11
+ 'an existing Wix Headless site',
12
+ 'a project download link',
13
+ 'a Wix site to move to code'
14
+ ];
15
+ // Like StartDeployWebsite's, these arguments are read by people via BI; only
16
+ // `startingPoint` changes the response.
17
+ export const START_HEADLESS_BUILD_PARAM_DESCRIPTIONS = {
18
+ userRequest: START_DEPLOY_WEBSITE_PARAM_DESCRIPTIONS.userRequest,
19
+ siteDescription: START_DEPLOY_WEBSITE_PARAM_DESCRIPTIONS.siteDescription,
20
+ startingPoint: 'What the build starts from: nothing yet; a design worked out in this conversation; an existing Wix Headless site; a project download link (a download.zip from Wix); or a Wix site to move to code.',
21
+ siteFunctionality: START_DEPLOY_WEBSITE_PARAM_DESCRIPTIONS.siteFunctionality,
22
+ agentIdentity: START_DEPLOY_WEBSITE_PARAM_DESCRIPTIONS.agentIdentity,
23
+ wixAccess: START_DEPLOY_WEBSITE_PARAM_DESCRIPTIONS.wixAccess
24
+ };
25
+ const PREFIX = "The following is Wix's headless guide. Follow it end to end and do the work yourself. If you find the user already has the site's code, call StartDeployWebsite instead.";
26
+ const MOVE_TO_CODE_LINE = 'Moving a Wix site to code starts from the site\'s dashboard (Headless settings, "Go Headless"), which hands the owner a prompt with the project\'s download link. Ask the user for that prompt, then follow the guide with it.';
27
+ export function startHeadlessBuildResponse(guide, startingPoint) {
28
+ const lines = [];
29
+ if (startingPoint === 'a Wix site to move to code') {
30
+ lines.push(MOVE_TO_CODE_LINE);
31
+ }
32
+ if (guide && guide.trim()) {
33
+ lines.push(PREFIX, '---', guide.trim());
34
+ }
35
+ else {
36
+ lines.push(`Wix's headless guide could not be loaded here. It is at ${HEADLESS_GUIDE_URL}: read it whole with ReadFullDocsArticle if you have that tool, otherwise fetch it with curl or your web tool, then follow it end to end and do the work yourself. If you find the user already has the site's code, call StartDeployWebsite instead.`);
37
+ }
38
+ return lines.join('\n\n');
39
+ }
40
+ export function addStartHeadlessBuildTool(server, disableTools = [], toolDescriptions, fetchOptions = {}) {
41
+ if (disableTools.includes(START_HEADLESS_BUILD_TOOL_NAME)) {
42
+ return;
43
+ }
44
+ const d = START_HEADLESS_BUILD_PARAM_DESCRIPTIONS;
45
+ server.tool(START_HEADLESS_BUILD_TOOL_NAME, toolDescriptions?.[START_HEADLESS_BUILD_TOOL_NAME] ??
46
+ defaultToolDescriptions[START_HEADLESS_BUILD_TOOL_NAME], {
47
+ userRequest: z.string().min(1).describe(d.userRequest),
48
+ siteDescription: z.string().min(1).describe(d.siteDescription),
49
+ startingPoint: z
50
+ .enum(START_HEADLESS_BUILD_STARTING_POINTS)
51
+ .describe(d.startingPoint),
52
+ siteFunctionality: z.string().min(1).describe(d.siteFunctionality),
53
+ agentIdentity: z.string().min(1).describe(d.agentIdentity),
54
+ wixAccess: z.string().min(1).describe(d.wixAccess)
55
+ }, { readOnlyHint: true, destructiveHint: false, openWorldHint: false }, async (args, { httpClient }) => {
56
+ // Inline, not a link: chat agents cannot fetch www.wix.com themselves.
57
+ let guide;
58
+ try {
59
+ guide = await fetchArticleContent(httpClient, HEADLESS_GUIDE_URL, 'article', true, fetchOptions.skillsPortalUrl, fetchOptions.repo, fetchOptions.commitHash);
60
+ }
61
+ catch (error) {
62
+ console.warn('[StartHeadlessBuild] guide fetch failed, returning the pointer:', error instanceof Error ? error.message : error);
63
+ }
64
+ return {
65
+ content: [
66
+ {
67
+ type: 'text',
68
+ text: startHeadlessBuildResponse(guide, args.startingPoint)
69
+ }
70
+ ]
71
+ };
72
+ });
73
+ }
74
+ //# sourceMappingURL=start-headless-build.js.map
@@ -163,7 +163,9 @@ function addExecuteGraphqlTool(server, description, authStrategy, options) {
163
163
  scope: z.enum(['site', 'account']).optional().describe(d.scope),
164
164
  hasMutations: z.boolean().describe(d.hasMutations),
165
165
  reason: z.string().describe(d.reason)
166
- }, { readOnlyHint: false, destructiveHint: true, openWorldHint: false }, async ({ query, variables, operationName, siteId, scope, hasMutations, reason }, extra) => {
166
+ },
167
+ // openWorldHint true: any operation in the Wix GraphQL schema, chosen at call time.
168
+ { readOnlyHint: false, destructiveHint: true, openWorldHint: true }, async ({ query, variables, operationName, siteId, scope, hasMutations, reason }, extra) => {
167
169
  const effectiveScope = scope ?? (siteId ? 'site' : 'account');
168
170
  logger.log(`[${EXECUTE_GRAPHQL_TOOL_NAME}] scope=${effectiveScope} siteId=${siteId ?? 'none'} hasMutations=${hasMutations} operationName=${operationName ?? '-'} reason="${reason}"`);
169
171
  if (effectiveScope === 'site' && !siteId) {
@@ -125,11 +125,11 @@ export function addImportClaudeDesignTool(server, authStrategy, options) {
125
125
  }
126
126
  const contentLength = Number(response.headers.get('content-length'));
127
127
  if (contentLength > maxBundleBytes) {
128
- return errorResult('The design is too large to import.');
128
+ return errorResult("The design is too large to import. This tool only takes Claude Design's bundle URL. To put this site live, call StartDeployWebsite with the site's files.");
129
129
  }
130
130
  const html = await readBodyWithLimit(response, maxBundleBytes);
131
131
  if (html === null) {
132
- return errorResult('The design is too large to import.');
132
+ return errorResult("The design is too large to import. This tool only takes Claude Design's bundle URL. To put this site live, call StartDeployWebsite with the site's files.");
133
133
  }
134
134
  try {
135
135
  const { id, outcome } = await initInstantSite(wixstroOptions, args.title, args.claude_design_project_id, INSTANT_SITE_ORIGIN);
@@ -22,6 +22,7 @@ export { createWixToolkit, extractText, type WixTool, type WixToolkit, type WixT
22
22
  export { fetchRecipesIndex, fetchArticle, RECIPES_INDEX_URL } from './docs/fetch-article.js';
23
23
  export { generateDocsNavigationTree, fetchMenuContent, MENU_CONTENT_THRESHOLD, normalizeMenuContent, summarizeLargeMenu, parseDirectChildren } from './docs/normalize-menu-content.js';
24
24
  export { addCodeModeTools, addExecuteCodeModeTool, addSearchCodeModeTool, type CodeModeFetch, type CodeModeOptions } from './code-mode/index.js';
25
+ export { addUploadHeadlessWebsiteFilesTool, UPLOAD_HEADLESS_WEBSITE_FILES_TOOL_NAME } from './api-call/upload-headless-website-files.js';
25
26
  export { validateExecuteCode, EXECUTE_FUNCTION_EXPRESSION_HINT, type CodeValidationResult } from './code-mode/validation.js';
26
27
  export { addGraphqlTools, resetGraphqlSchemaCache, GRAPHQL_TOOL_NAMES, SEARCH_GRAPHQL_TOOL_NAME, INSPECT_GRAPHQL_TOOL_NAME, EXECUTE_GRAPHQL_TOOL_NAME, WIX_GRAPHQL_ENDPOINT, type GraphqlToolsOptions, type GraphqlToolName } from './graphql/index.js';
27
28
  export { defaultConfig, defaultToolDescriptions, defaultReadmeDocs, widgetSiteCreationConfig, SITE_CREATION_COPY, toWidget, executeCodeModeToolDescriptions, SYSTEM_REMINDER_GUIDELINES, SYSTEM_REMINDER, mergeConfig, type ModeDefaultConfig } from './config/default-config.js';
@@ -26,6 +26,7 @@ export { fetchRecipesIndex, fetchArticle, RECIPES_INDEX_URL } from './docs/fetch
26
26
  export { generateDocsNavigationTree, fetchMenuContent, MENU_CONTENT_THRESHOLD, normalizeMenuContent, summarizeLargeMenu, parseDirectChildren } from './docs/normalize-menu-content.js';
27
27
  // Code mode (search + execute via sandboxed JS)
28
28
  export { addCodeModeTools, addExecuteCodeModeTool, addSearchCodeModeTool } from './code-mode/index.js';
29
+ export { addUploadHeadlessWebsiteFilesTool, UPLOAD_HEADLESS_WEBSITE_FILES_TOOL_NAME } from './api-call/upload-headless-website-files.js';
29
30
  export { validateExecuteCode, EXECUTE_FUNCTION_EXPRESSION_HINT } from './code-mode/validation.js';
30
31
  // GraphQL tools (search operations + inspect schema + execute)
31
32
  export { addGraphqlTools, resetGraphqlSchemaCache, GRAPHQL_TOOL_NAMES, SEARCH_GRAPHQL_TOOL_NAME, INSPECT_GRAPHQL_TOOL_NAME, EXECUTE_GRAPHQL_TOOL_NAME, WIX_GRAPHQL_ENDPOINT } from './graphql/index.js';
@@ -21,7 +21,8 @@ const BLANK_CANVAS_IMAGE_URL = 'https://images-wixmp-530a50041672c69d335ba4cf.wi
21
21
  const BLANK_CANVAS_DESCRIPTION = 'This Blank Canvas Responsive Template is ready to be customized to your exact needs.';
22
22
  const BLANK_CANVAS_META_SITE_ID = {
23
23
  studio: 'fe86a14e-ef67-49b4-a409-d086f3abaa1a',
24
- harmony: '91532250-8835-46ac-9666-e4db8770b275'
24
+ harmony: '91532250-8835-46ac-9666-e4db8770b275',
25
+ classic: 'b55bdf43-95e0-4cef-b9bb-92dcc7af2742'
25
26
  };
26
27
  /**
27
28
  * Searches Wix templates server-side. Widget clients render a gallery to pick from
@@ -55,9 +56,9 @@ export function addSearchSiteTemplatesTool(server, _authStrategy, options) {
55
56
  defaultToolDescriptions[SEARCH_SITE_TEMPLATES_TOOL_NAME],
56
57
  inputSchema: {
57
58
  builder: z
58
- .enum(['harmony', 'studio'])
59
+ .enum(['harmony', 'studio', 'classic'])
59
60
  .default('harmony')
60
- .describe('Which builder\'s templates to return: "studio" if the user asked for Wix Studio in this site creation flow, otherwise "harmony" (the default). You choose this from the request — don\'t ask the user which builder.'),
61
+ .describe('Which builder\'s templates to return: "studio" if the user asked for Wix Studio in this site creation flow, "classic" if they asked for the Classic Editor (the Wix Editor), otherwise "harmony" (the default). You choose this from the request — don\'t ask the user which builder.'),
61
62
  query: z
62
63
  .string()
63
64
  .min(1)
@@ -185,10 +186,19 @@ function blankCanvasCard(builder) {
185
186
  };
186
187
  }
187
188
  async function searchSiteTemplates(builder, query, limit) {
188
- // Studio is selected via bookType; Harmony via the templateBuilders filter.
189
- const builderParams = builder === 'harmony'
190
- ? { filter: { templateBuilders: [TemplateBuilder.Harmony] } }
191
- : { bookType: 'studio' };
189
+ // Studio is selected via bookType; Harmony and the Classic Editor via the
190
+ // templateBuilders filter (bookType "main-v2" now returns Harmony templates).
191
+ const builderParams = builder === 'studio'
192
+ ? { bookType: 'studio' }
193
+ : {
194
+ filter: {
195
+ templateBuilders: [
196
+ builder === 'classic'
197
+ ? TemplateBuilder.Editor
198
+ : TemplateBuilder.Harmony
199
+ ]
200
+ }
201
+ };
192
202
  const response = await httpClient.request(searchTemplates({
193
203
  language: 'en',
194
204
  query: query.trim(),
@@ -126,9 +126,12 @@ export interface ReadmeDocConfig {
126
126
  }
127
127
  export interface DocsToolsOptions {
128
128
  getToKnowWixEnabled?: boolean;
129
+ /** @deprecated CreateWixBusinessGuide was removed (StartHeadlessBuild replaces its headless route); ignored. */
129
130
  createWixBusinessGuideEnabled?: boolean;
130
131
  /** StartDeployWebsite (publish ready-made site files) — an account-owner flow; off for visitor servers. */
131
132
  startDeployWebsiteEnabled?: boolean;
133
+ /** StartHeadlessBuild (build a new site in code) — an account-owner flow; off for visitor servers. */
134
+ startHeadlessBuildEnabled?: boolean;
132
135
  disableTools?: string[];
133
136
  /** Custom descriptions for tools, keyed by tool name */
134
137
  toolDescriptions?: Record<string, string>;
@@ -152,8 +155,7 @@ export interface DocsToolsOptions {
152
155
  dynamicContextEnabled?: boolean;
153
156
  /** Enable partner context section in dynamic context output */
154
157
  partnerContextEnabled?: boolean;
155
- /** Whether the client is a CLI environment (e.g. Claude Code) where users can run terminal commands.
156
- * Accepts a boolean or a function for lazy evaluation (useful when client name is only known after MCP init). */
158
+ /** @deprecated Only CreateWixBusinessGuide read it, and that tool was removed; ignored. */
157
159
  cliEnabled?: boolean | (() => boolean);
158
160
  /** Use the new platformized semantic search API (POST /v1/docs/search) instead of the legacy GET endpoint */
159
161
  usePlatformizedSearch?: boolean;
@@ -126,9 +126,12 @@ export interface ReadmeDocConfig {
126
126
  }
127
127
  export interface DocsToolsOptions {
128
128
  getToKnowWixEnabled?: boolean;
129
+ /** @deprecated CreateWixBusinessGuide was removed (StartHeadlessBuild replaces its headless route); ignored. */
129
130
  createWixBusinessGuideEnabled?: boolean;
130
131
  /** StartDeployWebsite (publish ready-made site files) — an account-owner flow; off for visitor servers. */
131
132
  startDeployWebsiteEnabled?: boolean;
133
+ /** StartHeadlessBuild (build a new site in code) — an account-owner flow; off for visitor servers. */
134
+ startHeadlessBuildEnabled?: boolean;
132
135
  disableTools?: string[];
133
136
  /** Custom descriptions for tools, keyed by tool name */
134
137
  toolDescriptions?: Record<string, string>;
@@ -152,8 +155,7 @@ export interface DocsToolsOptions {
152
155
  dynamicContextEnabled?: boolean;
153
156
  /** Enable partner context section in dynamic context output */
154
157
  partnerContextEnabled?: boolean;
155
- /** Whether the client is a CLI environment (e.g. Claude Code) where users can run terminal commands.
156
- * Accepts a boolean or a function for lazy evaluation (useful when client name is only known after MCP init). */
158
+ /** @deprecated Only CreateWixBusinessGuide read it, and that tool was removed; ignored. */
157
159
  cliEnabled?: boolean | (() => boolean);
158
160
  /** Use the new platformized semantic search API (POST /v1/docs/search) instead of the legacy GET endpoint */
159
161
  usePlatformizedSearch?: boolean;
@@ -34,6 +34,7 @@ import { addDocsTools } from './docs/docs.js';
34
34
  import { addApiCallTool } from './api-call/index.js';
35
35
  import { addGraphqlTools, GRAPHQL_TOOL_NAMES } from './graphql/index.js';
36
36
  import { addExecuteCodeModeTool, addSearchCodeModeTool } from './code-mode/index.js';
37
+ import { addUploadHeadlessWebsiteFilesTool } from './api-call/upload-headless-website-files.js';
37
38
  import { defaultReadmeDocs, executeCodeModeToolDescriptions, buildToolDescriptions } from './config/default-config.js';
38
39
  import { getDynamicContext } from './docs/get-to-know.js';
39
40
  import { createPanoramaClient } from './infra/panorama.js';
@@ -227,6 +228,14 @@ export function createWixToolkit(options) {
227
228
  maxResponseSize
228
229
  });
229
230
  }
231
+ if (requestedTools.has('UploadHeadlessWebsiteFiles') &&
232
+ !disableTools?.includes('UploadHeadlessWebsiteFiles')) {
233
+ addUploadHeadlessWebsiteFilesTool(server, {
234
+ authStrategy,
235
+ toolDescriptions: effectiveToolDescriptions,
236
+ clientName
237
+ });
238
+ }
230
239
  // GraphQL tools register only the ones requested (each is opt-in by name).
231
240
  const requestedGraphqlTools = GRAPHQL_TOOL_NAMES.filter((name) => requestedTools.has(name));
232
241
  if (requestedGraphqlTools.length > 0) {
@@ -51,6 +51,8 @@ export declare class WixMcpServer extends McpServer {
51
51
  constructor(serverInfo: Implementation, options?: ServerOptions, context?: WixMcpServerContext | undefined);
52
52
  setUserIdGetter(getUserId: () => string | undefined): void;
53
53
  getSessionId(): string;
54
+ /** The connected client's name: the host's getter (User-Agent fallback) first, then clientInfo. */
55
+ clientName(): string | undefined;
54
56
  setClientNameGetter(getClientName: () => string | undefined): void;
55
57
  setUserAgentGetter(getUserAgent: () => string | undefined): void;
56
58
  setGptAppSchemesEnabled(enabled: boolean): void;
@@ -39,6 +39,10 @@ export class WixMcpServer extends McpServer {
39
39
  getSessionId() {
40
40
  return this.sessionId;
41
41
  }
42
+ /** The connected client's name: the host's getter (User-Agent fallback) first, then clientInfo. */
43
+ clientName() {
44
+ return this.getClientName?.() ?? this.server.getClientVersion()?.name;
45
+ }
42
46
  setClientNameGetter(getClientName) {
43
47
  this.getClientName = getClientName;
44
48
  }