@prontosite/mcp 0.14.4 → 0.14.6

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/CHANGELOG.md CHANGED
@@ -3,6 +3,19 @@
3
3
  Alle nennenswerten Änderungen am MCP-Server für ProntoSite. Der Server ist ein dünner Client um die
4
4
  ProntoSite Deploy-API; die eigentliche Logik lebt serverseitig.
5
5
 
6
+ ## 0.14.6 – 2026-10-27
7
+
8
+ - Instructions 2c: neues Entwurfs-Limit je Website – 300 Änderungen je Stunde, davon 30 direkt hintereinander (Kunden und
9
+ Betreuer gleich). Bei 429 nicht aufgeben, sondern `retryAfter` Sekunden warten und weitermachen.
10
+ - Fehler mit HTTP 429 tragen `status`, `rateLimited` und `retryAfter` im `structuredContent` (vorher nur der Text);
11
+ Server-Texte mit „erneut versuchen" werden unverändert durchgereicht.
12
+
13
+ ## 0.14.5 – 2026-10-24
14
+
15
+ Enthält 0.14.3 und 0.14.4 (nie einzeln veröffentlicht).
16
+ - Instructions 3a: Ab Starter ist „Änderungen sofort live" der Standard („Sag es, und es ist live."). Absicherung sind Verlauf
17
+ und `site_undo`. Maßgeblich bleibt `site_status.autoPublish`.
18
+
6
19
  ## 0.14.4 – 2026-10-24
7
20
 
8
21
  Enthält 0.14.3 (nie einzeln veröffentlicht).
package/api.mjs CHANGED
@@ -116,7 +116,7 @@ export function friendlyApiError(status, serverError = "") {
116
116
  if (status === 403 && /API-Zugang nicht im Tarif|Starter-Plan/i.test(raw))
117
117
  return "Dein ProntoSite-Tarif enthält keinen API-Zugang. Wähle im Dashboard → Zahlung einen Tarif oder bitte deinen Betreuer um eine API-Freigabe.";
118
118
  if (status === 429) // Server nennt Wartezeit + richtigen Weg → durchreichen; sonst allgemeiner Hinweis
119
- return /wieder möglich in/.test(raw) ? raw : "Zu viele Anfragen in kurzer Zeit (Rate-Limit). Bitte einen Moment warten und erneut versuchen.";
119
+ return /wieder möglich in|erneut versuchen/.test(raw) ? raw : "Zu viele Anfragen in kurzer Zeit (Rate-Limit). Bitte einen Moment warten und erneut versuchen, Änderungen bündeln.";
120
120
  return raw || `HTTP ${status}`;
121
121
  }
122
122
 
@@ -127,7 +127,11 @@ async function asJson(res) {
127
127
  if (!res.ok) {
128
128
  // Website-Auflösung (Firmenname/Domain): Kandidaten bzw. Vorschläge in die Meldung, damit der Assistent nachfragen kann.
129
129
  const list = (body.candidates || body.suggestions || []).map(e => `${e.slug || e.site}${e.name ? ` (${e.name})` : ""}`).join(", ");
130
- throw new Error(friendlyApiError(res.status, body.error) + (list ? ` ${body.candidates ? "Kandidaten" : "Ähnlich"}: ${list}.` : ""));
130
+ const err = new Error(friendlyApiError(res.status, body.error) + (list ? ` ${body.candidates ? "Kandidaten" : "Ähnlich"}: ${list}.` : ""));
131
+ // 429: Status + Wartezeit maschinenlesbar mitgeben (structuredContent über asError) – die KI soll warten statt aufgeben.
132
+ err.status = res.status;
133
+ if (res.status === 429) { err.rateLimited = true; err.retryAfter = Number(body.retryAfter) || Number(res.headers?.get?.("retry-after")) || null; }
134
+ throw err;
131
135
  }
132
136
  return body;
133
137
  }
package/index.mjs CHANGED
@@ -21,7 +21,7 @@ const cfg = loadConfig();
21
21
  // es im MCP-Log/Terminal auffällt; die endgültige Auflösung (Betreuer-Token-Vorrang vs. Map) klärt sites_list.
22
22
  for (const w of (cfg.warnings || [])) process.stderr.write("[prontosite-mcp] ⚠ " + w + "\n");
23
23
  // instructions: Arbeitsweise (Weg B = Standard) – gleicher Text wie am Remote-Endpunkt.
24
- const server = new McpServer({ name: "prontosite", version: "0.14.4" }, { instructions: instructionsFor("local") });
24
+ const server = new McpServer({ name: "prontosite", version: "0.14.5" }, { instructions: instructionsFor("local") });
25
25
  // Tool-Definitionen: gemeinsame Quelle mit dem Remote-Endpunkt (tools.mjs, Konzept KI-Anbindung §4.2).
26
26
  registerTools(server, { z, cfg, mode: "local" });
27
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prontosite/mcp",
3
- "version": "0.14.4",
3
+ "version": "0.14.6",
4
4
  "description": "MCP-Server für ProntoSite – Website-Status, Export, Deploy und Veröffentlichen direkt aus einem KI-Assistenten (Claude Desktop). Dünner Client um die ProntoSite Deploy-API.",
5
5
  "type": "module",
6
6
  "bin": {
package/tools.mjs CHANGED
@@ -30,7 +30,7 @@ const instructionLines = mode => [
30
30
  + "scope:\"all\" (bei Bedarf region:\"footer\"/\"header\") – EIN Aufruf für alle Seiten, inkl. tel:/mailto:-Links. NIE Seite für Seite per "
31
31
  + "site_file_put. Meldet die Antwort company, zusätzlich site_company_set für die Firmendaten (Impressum/Datenschutz/Kontakt).",
32
32
  "2c. Für Markup über alle Seiten (z. B. Footer-HTML) site_edit_html mit scope:\"all\" (ggf. region:\"footer\"), nie Seite für Seite per site_file_put. "
33
- + "Schreib-Limit je 10 Minuten: Kunden 30, Betreuer 200 Aufrufe – dieselbe Änderung auf vielen Seiten ist EIN Aufruf (site_edit_text scope:\"all\" bzw. site_edit_html).",
33
+ + "Entwurfs-Limit je Website: 300 Änderungen je Stunde, davon 30 direkt hintereinander (Kunden und Betreuer gleich) – dieselbe Änderung auf vielen Seiten ist EIN Aufruf (site_edit_text scope:\"all\" bzw. site_edit_html). Bei 429 (rateLimited) NICHT aufgeben: retryAfter Sekunden warten, dann weitermachen; bisherige Änderungen bleiben gespeichert.",
34
34
  "2d. Badge nie im HTML ändern, nachbauen oder entfernen – es wird beim Ausliefern erzeugt (data-ps=\"badge\"; site_edit_text/site_edit_html/site_file_put lehnen das ab, erlaubt ist nur das Wiederherstellen des Original-Markers).",
35
35
  "2b. Für Übersetzungen und Textüberarbeitung: site_page_texts → Texte übersetzen/überarbeiten → site_page_texts_set, JE SEITE ein Aufruf "
36
36
  + "(neue Sprachfassung vorher mit site_page_copy, z. B. index.html → en/index.html). NIE HTML über site_file_put umschreiben. "
@@ -38,7 +38,8 @@ const instructionLines = mode => [
38
38
  "3. Veröffentlichen (site_publish, publish=true) NUR nach ausdrücklicher Bestätigung des Nutzers im Chat – bis dahin bleibt alles im Entwurf. "
39
39
  + "Änderungen im Entwurf BÜNDELN und am Ende EINMAL veröffentlichen, nicht nach jedem Schritt (Vorschau über previewUrl). Limit: Kunden 30, "
40
40
  + "Betreuer 120 Veröffentlichungen je Stunde (je 10 direkt hintereinander); bei 429 retryAfter abwarten, der Entwurf bleibt erhalten.",
41
- "3a. Wenn site_status autoPublish:true meldet („Änderungen sofort live\"): nicht nach Veröffentlichung fragen und nicht „Entwurf\" sagen – "
41
+ "3a. Ab Starter ist „Änderungen sofort live\" Standard („Sag es, und es ist live.\"); Absicherung sind Verlauf und site_undo. "
42
+ + "Wenn site_status autoPublish:true meldet: nicht nach Veröffentlichung fragen und nicht „Entwurf\" sagen – "
42
43
  + "„ist live\" melden (geht nach ca. 5 s automatisch live, Folgen von Änderungen werden gebündelt); Vorschau-Link entfällt; site_undo "
43
44
  + "veröffentlicht sofort mit. Weiterhin NUR nach Bestätigung des Nutzers: Domain verbinden/trennen, Rechtstexte-Einstellungen "
44
45
  + "(Firmendaten, site_legal_options, Impressum/Datenschutz) und Löschen von Seiten. Meldet eine Antwort autoPublish.state \"held\", "
@@ -82,7 +83,8 @@ export function toolAnnotations(name, mode = "local") {
82
83
  export const toStructured = obj => (obj && typeof obj === "object" && !Array.isArray(obj) ? obj : Array.isArray(obj) ? { items: obj } : { value: obj ?? null });
83
84
  export const asText = obj => ({ content: [{ type: "text", text: JSON.stringify(obj, null, 2) }], structuredContent: toStructured(obj) });
84
85
  export const asError = e => { const msg = e?.message || String(e);
85
- return { isError: true, content: [{ type: "text", text: "Fehler: " + msg }], structuredContent: { error: msg, ...(e?.status ? { status: e.status } : {}) } }; };
86
+ return { isError: true, content: [{ type: "text", text: "Fehler: " + msg }], structuredContent: { error: msg, ...(e?.status ? { status: e.status } : {}),
87
+ ...(e?.rateLimited ? { rateLimited: true, retryAfter: e.retryAfter ?? null } : {}) } }; };
86
88
 
87
89
  /** Ausgabe-Schema von site_file_get (structuredContent; OpenAI Apps SDK: outputSchema für Tools mit structuredContent). */
88
90
  const FILE_GET_OUTPUT = z => z.object({