bricks-builder-mcp 3.6.5 → 3.7.2

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 (3) hide show
  1. package/README.md +105 -33
  2. package/package.json +3 -2
  3. package/server.js +144 -0
package/README.md CHANGED
@@ -1,28 +1,44 @@
1
1
  # Bricks Builder MCP
2
2
 
3
- Serveur **Model Context Protocol (MCP)** qui permet à Claude (Desktop, Cowork, Claude Code) de piloter **Bricks Builder** sur un site WordPress : lister les pages, lire/modifier le JSON Bricks, ajouter ou réorganiser des sections, etc.
3
+ Serveur **Model Context Protocol (MCP)** qui permet à Claude (Desktop, Cowork, Claude Code) de **piloter Bricks Builder** sur un site WordPress : créer des pages, ajouter des sections, modifier des éléments, uploader des images optimisées, vérifier visuellement le rendu, etc.
4
4
 
5
- ## Architecture
5
+ 💬 **Communauté Discord** : [https://discord.gg/rX22zHRzH](https://discord.gg/rX22zHRzH) — discussions Bricks + IA, partage de builds, signalement de bugs.
6
+
7
+ ---
8
+
9
+ ## Comment ça marche
6
10
 
7
11
  ```
8
- Claude (Desktop / Cowork)
12
+ Claude (Desktop / Cowork / Code)
9
13
  ↓ MCP (stdio)
10
- bricks-builder-mcp (ce package)
11
- ↓ HTTPS + X-API-Key
14
+ bricks-builder-mcp ce package npm, lancé par Claude
15
+ ↓ HTTPS + clé API
12
16
  WordPress + plugin "Bricks Builder MCP Server"
13
17
 
14
- Pages Bricks Builder
18
+ Tes pages Bricks Builder
15
19
  ```
16
20
 
17
- ## Installation
21
+ Tu installes **2 choses** :
22
+ 1. Le plugin WordPress (sur ton site)
23
+ 2. Le serveur MCP (ce package npm, lancé automatiquement par Claude)
24
+
25
+ ---
26
+
27
+ ## Installation en 4 étapes
28
+
29
+ ### 1. Installer le plugin WordPress
18
30
 
19
- ### Prérequis côté WordPress
31
+ Télécharge la dernière version ici → **[Releases GitHub](https://github.com/Scott1012/bricks-builder-mcp/releases)** (fichier `bricks-mcp.zip`).
20
32
 
21
- Le plugin compagnon **Bricks Builder MCP Server** doit être installé et activé sur le WordPress cible. Il expose les endpoints REST `/wp-json/bricks-mcp/v2/*` et permet de générer la clé API.
33
+ Dans WP admin Extensions Ajouter Téléverser une extension choisis le `.zip` Activer.
22
34
 
23
- ### Configuration côté Claude
35
+ ### 2. Générer ta clé API
24
36
 
25
- Ajoute dans le fichier de configuration Claude (`claude_desktop_config.json` ou équivalent) :
37
+ Dans WP admin **Réglages Bricks MCP** → clique "Générer une clé API" → copie-la (commence par `bricks_...`).
38
+
39
+ ### 3. Configurer Claude Desktop
40
+
41
+ Édite ton fichier `claude_desktop_config.json` (Cmd+, dans Claude Desktop → Developer → Edit Config) :
26
42
 
27
43
  ```json
28
44
  {
@@ -31,7 +47,7 @@ Ajoute dans le fichier de configuration Claude (`claude_desktop_config.json` ou
31
47
  "command": "npx",
32
48
  "args": ["-y", "bricks-builder-mcp"],
33
49
  "env": {
34
- "WORDPRESS_URL": "https://exemple-de-site.com",
50
+ "WORDPRESS_URL": "https://ton-site.com",
35
51
  "API_KEY": "bricks_xxxxxxxx"
36
52
  }
37
53
  }
@@ -39,32 +55,88 @@ Ajoute dans le fichier de configuration Claude (`claude_desktop_config.json` ou
39
55
  }
40
56
  ```
41
57
 
42
- Redémarre Claude. C'est tout.
58
+ Remplace `WORDPRESS_URL` par l'URL de ton site et `API_KEY` par la clé copiée à l'étape 2.
59
+
60
+ ### 4. Pour utiliser `verify_element` (recommandé) — 1 commande supplémentaire
61
+
62
+ Dans un terminal, lance une fois :
63
+
64
+ ```bash
65
+ npx playwright install chromium
66
+ ```
67
+
68
+ Ça télécharge Chromium (~130 Mo) pour que Claude puisse prendre des screenshots de tes pages et vérifier le rendu visuellement.
69
+
70
+ ### Redémarre Claude Desktop. C'est tout.
71
+
72
+ Demande à Claude : *"Liste les pages Bricks de mon site"* — si ça répond, tout marche.
73
+
74
+ ---
43
75
 
44
76
  ## Variables d'environnement
45
77
 
46
78
  | Variable | Requis | Description |
47
79
  |---|---|---|
48
- | `WORDPRESS_URL` | oui | URL racine du site WordPress (ex : `https://exemple.com`) |
49
- | `API_KEY` | oui | Clé API générée dans les réglages du plugin WordPress |
50
- | `INSECURE_SSL` | non | `true` pour désactiver la vérification SSL (utile en pré-prod avec certificat invalide). **N'utiliser qu'en pré-prod !** |
51
-
52
- ## Outils MCP exposés
53
-
54
- | Outil | Description |
55
- |---|---|
56
- | `list_bricks_pages` | Liste toutes les pages Bricks |
57
- | `get_page_json` | Récupère le JSON complet d'une page |
58
- | `update_page_json` | Sauvegarde le JSON complet d'une page |
59
- | `analyze_json_structure` | Analyse la structure d'un JSON Bricks |
60
- | `get_page_structure` | Vue d'ensemble légère (économe en tokens) |
61
- | `find_elements` | Recherche d'éléments par critères |
62
- | `get_element` | Récupère un élément précis |
63
- | `update_element` | Modifie un élément précis |
64
- | `add_element` | Ajoute un élément |
65
- | `batch_add` | Ajoute plusieurs éléments en une fois |
66
- | `delete_element` | Supprime un élément |
67
- | `reorder_sections` | Réorganise l'ordre des sections (header en haut, footer en bas) |
80
+ | `WORDPRESS_URL` | oui | URL de ton site (ex : `https://mon-site.com`) |
81
+ | `API_KEY` | oui | Clé API (générée à l'étape 2) |
82
+ | `INSECURE_SSL` | non | `true` pour ignorer un certificat SSL invalide. **Pré-prod uniquement.** |
83
+
84
+ ---
85
+
86
+ ## Outils disponibles (résumé)
87
+
88
+ **Pages & structure**
89
+ - `list_bricks_pages`, `get_page_structure`, `get_page_json`, `update_page_json`
90
+ - `create_page`, `delete_page`, `update_page_meta`, `duplicate_page`, `set_homepage`
91
+
92
+ **Éléments**
93
+ - `find_elements`, `get_element`, `update_element` (avec param `label` pour renommer dans le builder), `add_element`, `batch_add`, `delete_element`, `reorder_sections`
94
+
95
+ **⭐ Vérification visuelle**
96
+ - `verify_element` screenshot crop + report (computed style vs settings attendus, fonts chargées, erreurs JS console, etc.). **À utiliser après chaque batch_add significatif.**
97
+
98
+ **⭐ Upload optimisé (v3.8+)**
99
+ - `upload_local_file`, `upload_local_files_batch` l'IA donne juste le path local, le MCP server lit le fichier, conversion WebP automatique (-80 à -95% de poids), renommage SEO via le `title`
100
+ - `upload_media`, `upload_media_batch` (accepte URL HTTP/HTTPS **ou** data URI)
101
+ - `list_media`
102
+
103
+ **Design system Bricks natif**
104
+ - `set_custom_code`, `get_custom_code` (CSS + scripts header/footer)
105
+ - `register_google_font_locally`, `list_custom_fonts`
106
+ - `list_color_palette`, `add_color_to_palette`
107
+ - `list_typography_scales`, `set_typography_scale`, `list_spacing_scales`, `set_spacing_scale`
108
+ - `list_global_classes`, `create_global_class`, `update_global_class`
109
+ - `list_theme_styles`, `create_theme_style`
110
+
111
+ **Menu, médias, navigation**
112
+ - `list_menus`, `add_menu_item`, `list_all_pages`
113
+
114
+ **Code & sécurité**
115
+ - `set_code_execution`, `get_code_execution_status`
116
+ - `set_page_custom_code`, `get_page_custom_code`
117
+
118
+ **Feedback (⭐ v3.7+)**
119
+ - `report_missing_feature` — si Bricks supporte une feature nativement mais que le MCP ne l'expose pas, le chat AI le remonte pour qu'on l'ajoute
120
+ - `list_missing_features`, `resolve_missing_feature`
121
+
122
+ Doc complète + cheat-sheets + patterns dans le skill `bricks-builder` embarqué dans le plugin WP.
123
+
124
+ ---
125
+
126
+ ## Mise à jour
127
+
128
+ Le plugin WP a un système d'auto-update via GitHub Releases. WP admin → Extensions → "Vérifier les mises à jour" → update.
129
+
130
+ Le serveur MCP se met à jour automatiquement au prochain lancement de Claude Desktop (grâce à `npx -y`).
131
+
132
+ ---
133
+
134
+ ## Aide
135
+
136
+ - Bug ou question → [Discord](https://discord.gg/rX22zHRzH)
137
+ - Issue technique → [GitHub Issues](https://github.com/Scott1012/bricks-builder-mcp/issues)
138
+
139
+ ---
68
140
 
69
141
  ## Licence
70
142
 
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "bricks-builder-mcp",
4
- "version": "3.6.5",
5
- "description": "Serveur MCP pour piloter Bricks Builder (WordPress) depuis Claude — édition de pages, gestion d'éléments, réordonnancement des sections, vérification visuelle + technique (verify_element).",
4
+ "version": "3.7.2",
5
+ "description": "Serveur MCP pour piloter Bricks Builder (WordPress) depuis Claude — édition de pages, gestion d'éléments, réordonnancement des sections, vérification visuelle (verify_element), upload optimisé WebP. Communauté Discord : https://discord.gg/rX22zHRzH",
6
+ "homepage": "https://discord.gg/rX22zHRzH",
6
7
  "main": "server.js",
7
8
  "bin": {
8
9
  "bricks-builder-mcp": "./server.js"
package/server.js CHANGED
@@ -76,6 +76,49 @@ process.on('exit', () => {
76
76
  try { _browser.close(); } catch {}
77
77
  }
78
78
  });
79
+
80
+ // ===== v3.7.0 — Helpers upload local =====
81
+ // Le MCP server tourne sur la machine user (lancé par Claude Desktop via stdio),
82
+ // donc il a accès direct au filesystem user. Il peut lire les fichiers et les
83
+ // encoder en base64 LOCALEMENT pour les envoyer au plugin sans jamais que les
84
+ // bytes passent dans le contexte de l'AI.
85
+
86
+ const MIME_BY_EXT = {
87
+ png: 'image/png',
88
+ jpg: 'image/jpeg',
89
+ jpeg: 'image/jpeg',
90
+ gif: 'image/gif',
91
+ webp: 'image/webp',
92
+ svg: 'image/svg+xml',
93
+ avif: 'image/avif',
94
+ mp4: 'video/mp4',
95
+ webm: 'video/webm',
96
+ mov: 'video/quicktime',
97
+ };
98
+
99
+ function readLocalFileAsDataUri(localPath) {
100
+ if (!fs.existsSync(localPath)) {
101
+ throw new Error(`Fichier introuvable : ${localPath}`);
102
+ }
103
+ const stat = fs.statSync(localPath);
104
+ if (!stat.isFile()) {
105
+ throw new Error(`Pas un fichier : ${localPath}`);
106
+ }
107
+ const ext = (localPath.split('.').pop() || '').toLowerCase();
108
+ const mime = MIME_BY_EXT[ext];
109
+ if (!mime) {
110
+ throw new Error(`Extension non supportée : ${ext} (formats: ${Object.keys(MIME_BY_EXT).join(', ')})`);
111
+ }
112
+ const bytes = fs.readFileSync(localPath);
113
+ const b64 = bytes.toString('base64');
114
+ return {
115
+ dataUri: `data:${mime};base64,${b64}`,
116
+ size: stat.size,
117
+ mime,
118
+ ext,
119
+ basename: localPath.split('/').pop(),
120
+ };
121
+ }
79
122
  process.on('SIGINT', () => {
80
123
  if (_browser) {
81
124
  try { _browser.close(); } catch {}
@@ -1014,6 +1057,51 @@ mcpServer.setRequestHandler(ListToolsRequestSchema, async () => {
1014
1057
  },
1015
1058
  },
1016
1059
 
1060
+ // ===== v3.7.0 — UPLOAD FROM LOCAL FILESYSTEM =====
1061
+ // Lit le fichier directement sur le disque (le MCP server tourne en local),
1062
+ // encode en base64 LOCALEMENT, et l'envoie au plugin via data URI.
1063
+ // L'AI ne voit JAMAIS les bytes — elle donne juste le path.
1064
+ {
1065
+ name: "upload_local_file",
1066
+ description: "⭐ UPLOAD OPTIMAL pour des fichiers locaux. L'AI donne juste le path, le MCP server lit le fichier en local et l'envoie au plugin. Aucun b64 ne transite par le contexte AI. Param `optimize: true` (recommandé) convertit en WebP qualité 80, redim à 2000px max, et renomme avec extension .webp. Idéal pour SEO + perf web. Retourne {success, id, url, filename, optimization: {originalSize, optimizedSize, savings}}.",
1067
+ inputSchema: {
1068
+ type: "object",
1069
+ properties: {
1070
+ localPath: { type: "string", description: "Chemin absolu du fichier local (ex: /Users/.../jt-assets/logo.png)" },
1071
+ title: { type: "string", description: "Titre WP (sert aussi de nom de fichier slugifié — utilisé pour SEO)" },
1072
+ alt: { type: "string", description: "Texte alternatif (OBLIGATOIRE pour SEO + accessibilité)" },
1073
+ caption: { type: "string", description: "Légende optionnelle" },
1074
+ optimize: { type: "boolean", description: "Convertit en WebP qualité 80, redim à 2000px max. Défaut: true (recommandé)." },
1075
+ },
1076
+ required: ["localPath"],
1077
+ },
1078
+ },
1079
+ {
1080
+ name: "upload_local_files_batch",
1081
+ description: "Upload plusieurs fichiers locaux en 1 appel. Même principe que upload_local_file mais en lot. Continue même si certains échouent. Recommandé pour intégrer un dossier d'assets (logos, photos, etc.) en 1 commande.",
1082
+ inputSchema: {
1083
+ type: "object",
1084
+ properties: {
1085
+ items: {
1086
+ type: "array",
1087
+ description: "Liste des fichiers à uploader",
1088
+ items: {
1089
+ type: "object",
1090
+ properties: {
1091
+ localPath: { type: "string", description: "Chemin absolu du fichier local" },
1092
+ title: { type: "string", description: "Titre WP (slugifié pour le nom de fichier)" },
1093
+ alt: { type: "string", description: "Alt SEO" },
1094
+ caption: { type: "string", description: "Légende" },
1095
+ },
1096
+ required: ["localPath"],
1097
+ },
1098
+ },
1099
+ optimize: { type: "boolean", description: "Convertit tous en WebP. Défaut: true." },
1100
+ },
1101
+ required: ["items"],
1102
+ },
1103
+ },
1104
+
1017
1105
  // ===== v3.6.0 — UPLOAD MEDIA BATCH =====
1018
1106
  {
1019
1107
  name: "upload_media_batch",
@@ -1733,9 +1821,65 @@ mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {
1733
1821
  case "upload_media_batch":
1734
1822
  result = await callWordPressAPI("/upload-media-batch", "POST", {
1735
1823
  items: args.items,
1824
+ optimize: args.optimize,
1736
1825
  });
1737
1826
  break;
1738
1827
 
1828
+ // ===== v3.7.0 — UPLOAD FROM LOCAL FILESYSTEM =====
1829
+ case "upload_local_file": {
1830
+ try {
1831
+ const fileData = readLocalFileAsDataUri(args.localPath);
1832
+ logToFile(`[upload_local_file] ${args.localPath} (${fileData.size} bytes ${fileData.mime})`);
1833
+ // Le b64 est généré ici, dans le MCP server. Il part vers le plugin
1834
+ // mais ne transite JAMAIS par le contexte AI.
1835
+ result = await callWordPressAPI("/upload-media", "POST", {
1836
+ sourceUrl: fileData.dataUri,
1837
+ title: args.title || fileData.basename.replace(/\.[^.]+$/, ''),
1838
+ alt: args.alt,
1839
+ caption: args.caption,
1840
+ optimize: args.optimize !== false, // défaut true
1841
+ });
1842
+ } catch (err) {
1843
+ result = { success: false, error: err.message, localPath: args.localPath };
1844
+ }
1845
+ break;
1846
+ }
1847
+
1848
+ case "upload_local_files_batch": {
1849
+ const batchItems = [];
1850
+ const readErrors = [];
1851
+ for (const item of (args.items || [])) {
1852
+ try {
1853
+ const fileData = readLocalFileAsDataUri(item.localPath);
1854
+ batchItems.push({
1855
+ sourceUrl: fileData.dataUri,
1856
+ title: item.title || fileData.basename.replace(/\.[^.]+$/, ''),
1857
+ alt: item.alt,
1858
+ caption: item.caption,
1859
+ });
1860
+ } catch (err) {
1861
+ readErrors.push({ localPath: item.localPath, error: err.message });
1862
+ }
1863
+ }
1864
+ if (batchItems.length === 0) {
1865
+ result = {
1866
+ success: false,
1867
+ error: "Aucun fichier lisible",
1868
+ readErrors,
1869
+ };
1870
+ break;
1871
+ }
1872
+ result = await callWordPressAPI("/upload-media-batch", "POST", {
1873
+ items: batchItems,
1874
+ optimize: args.optimize !== false, // défaut true
1875
+ });
1876
+ // Joindre les erreurs de lecture locales au résultat
1877
+ if (readErrors.length > 0) {
1878
+ result.localReadErrors = readErrors;
1879
+ }
1880
+ break;
1881
+ }
1882
+
1739
1883
  default:
1740
1884
  console.error(`[LOG] Tool inconnu: ${name}`);
1741
1885
  result = { error: `Tool ${name} not found` };