Skip to content

Commit 58960b9

Browse files
committed
theme-check validation tool for theme files
1 parent 4eabe3b commit 58960b9

File tree

5 files changed

+575
-5
lines changed

5 files changed

+575
-5
lines changed

package-lock.json

Lines changed: 185 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
"description": "A command line tool for setting up Shopify Dev MCP server",
1919
"dependencies": {
2020
"@modelcontextprotocol/sdk": "^1.6.1",
21+
"@shopify/theme-check-common": "^3.19.0",
22+
"@shopify/theme-check-docs-updater": "^3.19.0",
2123
"graphql": "^16.11.0",
2224
"zod": "^3.24.2"
2325
},

src/tools/index.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { ValidationToolResult } from "../types.js";
1010
import { ValidationResult } from "../types.js";
1111
import validateGraphQLOperation from "../validations/graphqlSchema.js";
1212
import { hasFailedValidation } from "../validations/index.js";
13+
import validateThemeCodeblocks from "../validations/themeCodeBlock.js";
1314
import { searchShopifyAdminSchema } from "./shopifyAdminSchema.js";
1415

1516
const polarisUnifiedEnabled =
@@ -279,6 +280,65 @@ export async function shopifyTools(server: McpServer): Promise<void> {
279280
},
280281
);
281282

283+
server.tool(
284+
"validate_theme_codeblocks",
285+
`This tool validates Liquid codeblocks, Liquid files, and supporting Theme files (e.g. JSON translation files, JSON config files, JSON template files, JavaScript files, CSS files, and SVG files) generated by LLMs to ensure they don't have hallucinated Liquid filters, or incorrect references. If the user asks for an LLM to generate or update Liquid code, this tool should always be used to ensure valid code and supporting files were generated. If the file references other files, the other files must also be validated as part of the theme.`,
286+
287+
withConversationId({
288+
codeblocks: z
289+
.array(
290+
z.object({
291+
fileName: z
292+
.string()
293+
.describe(
294+
"The filename of the codeblock. If the filename is not provided, the filename should be descriptive of the codeblock's purpose, and should be in dashcase. Include file extension in the filename.",
295+
),
296+
fileType: z
297+
.enum([
298+
"blocks",
299+
"snippets",
300+
"sections",
301+
"layout",
302+
"config",
303+
"locales",
304+
"assets",
305+
])
306+
.default("blocks")
307+
.describe(
308+
"The type of codeblock generated. All JavaScript, CSS, and SVG files are in assets folder. Locale files are JSON files located in the locale folder. If the translation is only used in schemas, it should be in `locales/en(.default).schema.json`; if the translation is used anywhere in the liquid code, it should be in `en(.default).json`. The brackets show an optional default locale. The locale code should be the two-letter code for the locale.",
309+
),
310+
content: z.string().describe("The content of the file."),
311+
}),
312+
)
313+
.describe("An array of codeblocks to validate."),
314+
}),
315+
async (params) => {
316+
const validationResponses = await validateThemeCodeblocks(
317+
params.codeblocks,
318+
);
319+
320+
recordUsage(
321+
"validate_theme_codeblocks",
322+
params,
323+
validationResponses,
324+
).catch(() => {});
325+
326+
const responseText = formatValidationResult(
327+
validationResponses,
328+
"Theme Codeblocks",
329+
);
330+
331+
return {
332+
content: [
333+
{
334+
type: "text" as const,
335+
text: responseText,
336+
},
337+
],
338+
};
339+
},
340+
);
341+
282342
const gettingStartedApis = await fetchGettingStartedApis();
283343

284344
const gettingStartedApiNames = gettingStartedApis.map((api) => api.name);

0 commit comments

Comments
 (0)