bricks-mcp-server 0.13.0 → 0.14.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/dist/contracts.js CHANGED
@@ -12,6 +12,13 @@ export const globalClassOperationsSchema = z.object({ expected_hash: z.string().
12
12
  export const manageTemplateSchema = z.object({ id: z.number().int().positive(), action: z.enum(["get", "update", "clone", "delete"]), expected_modified: z.string().optional(), title: z.string().optional(), status: z.enum(["draft", "publish", "private"]).optional(), type: z.string().optional(), content: z.array(z.any()).optional(), settings: z.record(z.any()).optional(), conditions: z.array(z.any()).optional(), force: z.boolean().optional() }).superRefine((v, ctx) => { if (v.action === "update" && !v.expected_modified)
13
13
  ctx.addIssue({ code: z.ZodIssueCode.custom, message: "expected_modified is required for update" }); });
14
14
  export const previewUrlSchema = z.object({ id: z.number().int().positive(), ttl: z.number().int().min(60).max(900).optional() });
15
+ export const dynamicDataSchema = z.object({ post_id: z.number().int().positive(), user_id: z.number().int().positive().optional(), context: z.enum(["text", "link", "image", "media"]).optional(), items: z.array(z.string().min(1).max(20000)).min(1).max(50) });
16
+ export const revisionsSchema = z.object({ post_id: z.number().int().positive(), action: z.enum(["list", "compare", "restore"]), from: z.union([z.number().int().positive(), z.literal("current")]).optional(), to: z.union([z.number().int().positive(), z.literal("current")]).optional(), revision_id: z.number().int().positive().optional(), expected_modified: z.string().optional() }).superRefine((v, ctx) => { if (v.action === "compare" && (v.from === undefined || v.to === undefined))
17
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "from and to are required" }); if (v.action === "restore" && (!v.revision_id || !v.expected_modified))
18
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "revision_id and expected_modified are required" }); });
19
+ export const customCssSchema = z.object({ action: z.enum(["get", "update"]), scope: z.enum(["global", "post"]), post_id: z.number().int().positive().optional(), css: z.string().max(204800).optional(), expected_hash: z.string().length(64).optional() }).superRefine((v, ctx) => { if (v.scope === "post" && !v.post_id)
20
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "post_id is required" }); if (v.action === "update" && (v.css === undefined || !v.expected_hash))
21
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "css and expected_hash are required" }); });
15
22
  export function buildToolRequest(name, args) {
16
23
  if (name === "bricks_update_page") {
17
24
  const parsed = updatePageSchema.parse(args);
@@ -48,6 +55,19 @@ export function buildToolRequest(name, args) {
48
55
  const parsed = previewUrlSchema.parse(args);
49
56
  return { path: `/preview/${parsed.id}`, method: "GET", query: parsed.ttl ? { ttl: String(parsed.ttl) } : undefined };
50
57
  }
58
+ if (name === "bricks_resolve_dynamic_data")
59
+ return { path: "/dynamic-data/resolve", method: "POST", body: dynamicDataSchema.parse(args) };
60
+ if (name === "bricks_manage_revisions") {
61
+ const parsed = revisionsSchema.parse(args);
62
+ const { post_id, action, ...body } = parsed;
63
+ return action === "list" ? { path: `/revisions/${post_id}`, method: "GET" } : { path: `/revisions/${post_id}/${action}`, method: "POST", body };
64
+ }
65
+ if (name === "bricks_manage_custom_css") {
66
+ const parsed = customCssSchema.parse(args);
67
+ const { action, scope, post_id, ...body } = parsed;
68
+ const query = { scope, ...(post_id ? { post_id: String(post_id) } : {}) };
69
+ return action === "get" ? { path: "/custom-css", method: "GET", query } : { path: "/custom-css", method: "PUT", query, body };
70
+ }
51
71
  if (name === "bricks_upload_media")
52
72
  return { path: "/media", method: "POST", body: uploadMediaSchema.parse(args) };
53
73
  if (name === "bricks_find_media_usage")
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ if (subcommand === "doctor" || subcommand === "diagnose") {
33
33
  if (process.env.WP_URL) {
34
34
  console.error(`[bricks-mcp] target WP_URL=${process.env.WP_URL} WP_USER=${process.env.WP_USER ?? "?"}`);
35
35
  }
36
- const server = new Server({ name: "bricks-mcp-server", version: "0.13.0" }, { capabilities: { tools: {} } });
36
+ const server = new Server({ name: "bricks-mcp-server", version: "0.14.0" }, { capabilities: { tools: {} } });
37
37
  const tools = [
38
38
  {
39
39
  name: "bricks_start_here",
@@ -400,6 +400,42 @@ const tools = [
400
400
  schema: z.object({ id: z.number().int().positive(), ttl: z.number().int().min(60).max(900).optional() }),
401
401
  handler: async (args) => wpRequest(`/preview/${args.id}`, { query: args.ttl ? { ttl: String(args.ttl) } : undefined }),
402
402
  }, {
403
+ name: "bricks_resolve_dynamic_data",
404
+ description: "Preview 1–50 Bricks dynamic-data strings against an explicit post and optional user context. Uses Bricks' public renderer and blocks remote {echo} execution.",
405
+ inputSchema: { type: "object", properties: { post_id: { type: "number" }, user_id: { type: "number" }, context: { type: "string", enum: ["text", "link", "image", "media"] }, items: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 50 } }, required: ["post_id", "items"], additionalProperties: false },
406
+ schema: z.object({ post_id: z.number().int().positive(), user_id: z.number().int().positive().optional(), context: z.enum(["text", "link", "image", "media"]).optional(), items: z.array(z.string().min(1).max(20000)).min(1).max(50) }),
407
+ handler: async (args) => wpRequest("/dynamic-data/resolve", { method: "POST", body: args }),
408
+ },
409
+ {
410
+ name: "bricks_manage_revisions",
411
+ description: "List, compare, or restore Bricks-aware WordPress revisions. Restore requires expected_modified, honors dry-run, and creates an undo revision first.",
412
+ inputSchema: { type: "object", properties: { post_id: { type: "number" }, action: { type: "string", enum: ["list", "compare", "restore"] }, from: { type: ["number", "string"] }, to: { type: ["number", "string"] }, revision_id: { type: "number" }, expected_modified: { type: "string" } }, required: ["post_id", "action"], additionalProperties: false },
413
+ schema: z.object({ post_id: z.number().int().positive(), action: z.enum(["list", "compare", "restore"]), from: z.union([z.number().int().positive(), z.literal("current")]).optional(), to: z.union([z.number().int().positive(), z.literal("current")]).optional(), revision_id: z.number().int().positive().optional(), expected_modified: z.string().optional() }).superRefine((v, ctx) => { if (v.action === "compare" && (v.from === undefined || v.to === undefined))
414
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "from and to are required for compare" }); if (v.action === "restore" && (!v.revision_id || !v.expected_modified))
415
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "revision_id and expected_modified are required for restore" }); }),
416
+ handler: async (args) => { const { post_id, action, ...body } = args; if (action === "list")
417
+ return wpRequest(`/revisions/${post_id}`); return wpRequest(`/revisions/${post_id}/${action}`, { method: "POST", body }); },
418
+ },
419
+ {
420
+ name: "bricks_manage_custom_css",
421
+ description: "Read or update global/post Bricks Custom CSS. Update requires the current hash, honors dry-run, snapshots the previous value, and regenerates assets.",
422
+ inputSchema: { type: "object", properties: { action: { type: "string", enum: ["get", "update"] }, scope: { type: "string", enum: ["global", "post"] }, post_id: { type: "number" }, css: { type: "string" }, expected_hash: { type: "string" } }, required: ["action", "scope"], additionalProperties: false },
423
+ schema: z.object({ action: z.enum(["get", "update"]), scope: z.enum(["global", "post"]), post_id: z.number().int().positive().optional(), css: z.string().max(204800).optional(), expected_hash: z.string().length(64).optional() }).superRefine((v, ctx) => { if (v.scope === "post" && !v.post_id)
424
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "post_id is required for post scope" }); if (v.action === "update" && (v.css === undefined || !v.expected_hash))
425
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "css and expected_hash are required for update" }); }),
426
+ handler: async (args) => { const { action, scope, post_id, ...body } = args; const query = { scope: String(scope), ...(post_id ? { post_id: String(post_id) } : {}) }; return action === "get" ? wpRequest("/custom-css", { query }) : wpRequest("/custom-css", { method: "PUT", query, body }); },
427
+ },
428
+ {
429
+ name: "bricks_manage_integrations",
430
+ description: "Inspect/create WooCommerce Bricks templates or inspect/test the configured signed outbound webhook.",
431
+ inputSchema: { type: "object", properties: { integration: { type: "string", enum: ["woocommerce", "webhook"] }, action: { type: "string", enum: ["status", "types", "list", "create", "test"] }, type: { type: "string" }, title: { type: "string" }, status: { type: "string" }, content: { type: "array" }, settings: { type: "object" }, conditions: { type: "array" } }, required: ["integration", "action"], additionalProperties: false },
432
+ schema: z.object({ integration: z.enum(["woocommerce", "webhook"]), action: z.enum(["status", "types", "list", "create", "test"]), type: z.string().optional(), title: z.string().optional(), status: z.enum(["draft", "publish", "private"]).optional(), content: z.array(z.any()).optional(), settings: z.record(z.any()).optional(), conditions: z.array(z.any()).optional() }).superRefine((v, ctx) => { if (v.integration === "webhook" && !["status", "test"].includes(v.action))
433
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "webhook supports status or test" }); if (v.integration === "woocommerce" && v.action === "create" && (!v.type || !v.title))
434
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "type and title are required for create" }); }),
435
+ handler: async (args) => { const { integration, ...body } = args; if (integration === "webhook")
436
+ return body.action === "status" ? wpRequest("/webhooks") : wpRequest("/webhooks", { method: "POST", body }); return body.action === "status" ? wpRequest("/woocommerce/templates") : wpRequest("/woocommerce/templates", { method: "POST", body }); },
437
+ },
438
+ {
403
439
  name: "bricks_get_global_classes",
404
440
  description: "Read Bricks global classes and their categories — useful before editing pages so styling stays consistent.",
405
441
  inputSchema: { type: "object", properties: {}, additionalProperties: false },
@@ -449,6 +485,10 @@ const TOOL_ANNOTATIONS = {
449
485
  bricks_get_global_classes: { readOnlyHint: true },
450
486
  bricks_get_theme_styles: { readOnlyHint: true },
451
487
  bricks_get_design_context: { readOnlyHint: true },
488
+ bricks_resolve_dynamic_data: { readOnlyHint: true },
489
+ bricks_manage_revisions: { readOnlyHint: false, destructiveHint: true },
490
+ bricks_manage_custom_css: { readOnlyHint: false, destructiveHint: true },
491
+ bricks_manage_integrations: { readOnlyHint: false, destructiveHint: false },
452
492
  bricks_get_element: { readOnlyHint: true },
453
493
  bricks_apply_element_operations: { readOnlyHint: false, destructiveHint: true },
454
494
  bricks_list_media: { readOnlyHint: true },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bricks-mcp-server",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Provider-agnostic MCP server that exposes Bricks Builder pages, templates, global classes and theme styles as tools. Works with any MCP-compatible client (Claude Code, Codex CLI, etc.).",
5
5
  "type": "module",
6
6
  "bin": {