@prontosite/mcp 0.12.0 → 0.12.1
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 +9 -0
- package/api.mjs +3 -2
- package/index.mjs +1 -1
- package/package.json +1 -1
- package/tools.mjs +15 -8
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
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.12.1 – 2026-10-19
|
|
7
|
+
|
|
8
|
+
- **`site_edit_text` in einem Aufruf für die ganze Website:** `scope:"all"` ersetzt alle Fundstellen auf allen Seiten sofort
|
|
9
|
+
(ein Rückgängig-Schritt), `region` (`footer`/`header`/`main`/`all`) begrenzt auf einen Bereich, `attributes` (Standard an)
|
|
10
|
+
ersetzt auch in Links (`tel:`/`mailto:` normalisiert, Ländervorwahl bleibt) und Attributen (`alt`, `title`, `meta content`).
|
|
11
|
+
Antwort je Seite gefunden/geändert; steht der Wert in den Firmendaten, verweist `company` auf `site_company_set`.
|
|
12
|
+
- Instructions: Kontaktdaten-, Text- und Link-Änderungen immer per `site_edit_text` mit `scope:"all"`, nie Seite für Seite per
|
|
13
|
+
`site_file_put`.
|
|
14
|
+
|
|
6
15
|
## 0.12.0 – 2026-10-19
|
|
7
16
|
|
|
8
17
|
- **Arbeitsweise im Server verankert:** Der MCP-Server liefert beim Verbinden `instructions` – Standard ist das Arbeiten direkt
|
package/api.mjs
CHANGED
|
@@ -389,9 +389,10 @@ export async function apiFileRename(cfg, { site, from, to, baseRev } = {}, fetch
|
|
|
389
389
|
}
|
|
390
390
|
|
|
391
391
|
/** POST /api/edit-text/<site> – Text über alle Seiten suchen + ersetzen (Entwurf, eine Undo-Einheit). 409 kommt als Objekt zurück. */
|
|
392
|
-
export async function apiEditText(cfg, { site, find, replace, pages = null, baseRev = null } = {}, fetchImpl = fetch) {
|
|
392
|
+
export async function apiEditText(cfg, { site, find, replace, scope = null, region = null, attributes = null, pages = null, baseRev = null } = {}, fetchImpl = fetch) {
|
|
393
393
|
const { token, slug } = resolveTarget(cfg, site);
|
|
394
|
-
const body = { find, replace, ...(
|
|
394
|
+
const body = { find, replace, ...(scope ? { scope } : {}), ...(region ? { region } : {}), ...(attributes === false ? { attributes: false } : {}),
|
|
395
|
+
...(Array.isArray(pages) && pages.length ? { pages } : {}), ...(Number.isInteger(baseRev) ? { baseRev } : {}) };
|
|
395
396
|
return asJsonOr409(await fetchImpl(`${baseUrl(cfg)}/edit-text/${encodeURIComponent(slug)}`, {
|
|
396
397
|
method: "POST", headers: { ...authHeaders(token, cfg), "content-type": "application/json" }, body: JSON.stringify(body) }));
|
|
397
398
|
}
|
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.12.
|
|
24
|
+
const server = new McpServer({ name: "prontosite", version: "0.12.1" }, { instructions: SERVER_INSTRUCTIONS });
|
|
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.12.
|
|
3
|
+
"version": "0.12.1",
|
|
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
|
@@ -22,6 +22,9 @@ export const SERVER_INSTRUCTIONS = [
|
|
|
22
22
|
+ "Danach dem Nutzer sagen, was geändert wurde, und den Vorschau-Link (previewUrl aus site_status) nennen.",
|
|
23
23
|
"2. AUSNAHME: site_export + Deploy (site_deploy bzw. deploy_upload_begin/deploy_commit) NUR, wenn der Nutzer ausdrücklich lokal arbeiten "
|
|
24
24
|
+ "möchte oder die Website komplett umgebaut wird.",
|
|
25
|
+
"2a. Für Text-, Link- und Kontaktdaten-Änderungen (Telefonnummer, E-Mail, Adresse, Öffnungszeiten) IMMER site_edit_text mit "
|
|
26
|
+
+ "scope:\"all\" (bei Bedarf region:\"footer\"/\"header\") – EIN Aufruf für alle Seiten, inkl. tel:/mailto:-Links. NIE Seite für Seite per "
|
|
27
|
+
+ "site_file_put. Meldet die Antwort company, zusätzlich site_company_set für die Firmendaten (Impressum/Datenschutz/Kontakt).",
|
|
25
28
|
"3. Veröffentlichen (site_publish, publish=true) NUR nach ausdrücklicher Bestätigung des Nutzers im Chat – bis dahin bleibt alles im Entwurf.",
|
|
26
29
|
"4. Konflikt (409, conflict:true): nicht erzwingen. Erst site_status aufrufen (zeigt, wer was geändert hat), Inhalt neu holen, Änderung "
|
|
27
30
|
+ "neu anwenden und mit der neuen draftRev erneut senden.",
|
|
@@ -106,19 +109,23 @@ export function registerTools(server, { z, cfg, mode = "local", remote = null })
|
|
|
106
109
|
|
|
107
110
|
server.tool(
|
|
108
111
|
"site_edit_text",
|
|
109
|
-
"SCHREIBEND (Entwurf, nicht live) – STANDARDWEG für Textänderungen (Telefonnummer, Öffnungszeiten, Preise, Sätze): sucht
|
|
110
|
-
+ "im sichtbaren Text
|
|
111
|
-
+ "
|
|
112
|
-
+ "
|
|
113
|
-
+ "
|
|
114
|
-
+ "
|
|
112
|
+
"SCHREIBEND (Entwurf, nicht live) – STANDARDWEG für Textänderungen (Telefonnummer, E-Mail, Öffnungszeiten, Preise, Sätze): sucht "
|
|
113
|
+
+ "`find` im sichtbaren Text UND (attributes, Standard an) in Links/Attributen (href inkl. tel:/mailto: – normalisiert –, alt, title, "
|
|
114
|
+
+ "meta content) ALLER Seiten und ersetzt durch `replace` – EIN Aufruf, EIN Rückgängig-Schritt, Formatierung bleibt. "
|
|
115
|
+
+ "scope:\"all\" = alle Fundstellen auf allen Seiten sofort ersetzen (für Kontaktdaten im Kopf-/Fußbereich: plus region:\"footer\" bzw. "
|
|
116
|
+
+ "\"header\"); ohne scope ändert der Server bei mehr als einer Fundstelle NICHTS und liefert nur die Liste (oder pages:[…]). "
|
|
117
|
+
+ "Antwort: pages = je Seite gefunden/geändert. Rechtstexte und geschützte Bereiche bleiben unberührt (skipped); steht der Wert in "
|
|
118
|
+
+ "den Firmendaten, nennt `company` das Feld → zusätzlich site_company_set. Nie stattdessen Seite für Seite site_file_put. "
|
|
115
119
|
+ "Vorher site_status, danach site_status; live erst nach Bestätigung mit site_publish.",
|
|
116
120
|
{ site: z.string().optional().describe(SITE_DESC),
|
|
117
121
|
find: z.string().describe("Genau der Text, wie er auf der Website steht (z. B. '02242 123456')."),
|
|
118
122
|
replace: z.string().describe("Neuer Text (reiner Text)."),
|
|
119
|
-
|
|
123
|
+
scope: z.enum(["all"]).optional().describe("\"all\" = alle Fundstellen auf allen (bzw. den per pages gewählten) Seiten in diesem Aufruf ersetzen. Standard für Kontaktdaten."),
|
|
124
|
+
region: z.enum(["all", "header", "main", "footer"]).default("all").describe("Nur in diesem Bereich suchen: footer (Fußbereich), header (Kopf/Navigation), main (Inhalt) oder all."),
|
|
125
|
+
attributes: z.boolean().default(true).describe("Auch Linkziele (href, tel:/mailto: normalisiert) und Attribute (alt, title, meta content) ersetzen."),
|
|
126
|
+
pages: z.array(z.string()).optional().describe("Optional: Seiten-IDs (aus der Fundstellen-Liste), auf denen ersetzt werden soll. Ohne pages und ohne scope:\"all\" nur bei genau EINER Fundstelle."),
|
|
120
127
|
baseRev: z.number().int().optional().describe("Optional: draftRev aus site_status (Konfliktschutz, 409 bei zwischenzeitlicher Änderung derselben Seite).") },
|
|
121
|
-
async ({ site, find, replace, pages, baseRev }) => { try { return asText(await apiEditText(cfg, { site, find, replace, pages, baseRev })); } catch (e) { return asError(e); } }
|
|
128
|
+
async ({ site, find, replace, scope, region, attributes, pages, baseRev }) => { try { return asText(await apiEditText(cfg, { site, find, replace, scope, region, attributes, pages, baseRev })); } catch (e) { return asError(e); } }
|
|
122
129
|
);
|
|
123
130
|
|
|
124
131
|
if (mode === "local") {
|