@prontosite/mcp 0.9.2 → 0.10.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 +22 -0
- package/README.md +6 -0
- package/api.mjs +16 -0
- package/index.mjs +37 -4
- package/package.json +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
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.10.1 – 2026-10-03
|
|
7
|
+
|
|
8
|
+
- **Fix:** In der `account_create`-Beschreibung beendeten gerade Anführungszeichen (`"`) innerhalb der
|
|
9
|
+
deutschen Quotes `„…"` den JS-String vorzeitig → `SyntaxError` beim Start (0.10.0 war nicht ladbar).
|
|
10
|
+
Alle Tool-Beschreibungen auf typografische `„…“` umgestellt.
|
|
11
|
+
- **Schutz gegen Wiederholung:** `prepublishOnly` (= `npm run check` + `npm run smoke`) prüft vor jedem
|
|
12
|
+
Publish `node --check index.mjs api.mjs` **und** einen echten Import-Smoke (`smoke.mjs` lädt `index.mjs`
|
|
13
|
+
komplett – alle `server.tool`-Registrierungen laufen – ohne den stdio-Server zu starten, Dummy-Env).
|
|
14
|
+
Derselbe Smoke läuft in `npm test` des Hauptprojekts. `index.mjs` startet den Server jetzt nur noch bei
|
|
15
|
+
Direktausführung (Main-Guard), damit der Import nicht blockiert.
|
|
16
|
+
|
|
17
|
+
## 0.10.0 – 2026-10-03
|
|
18
|
+
|
|
19
|
+
- **Neu: `account_create`** (schreibend, nur mit Betreuer-Token: admin/partner/agentur) – legt ein neues
|
|
20
|
+
Kundenkonto an (Dashboard-Weg „Kunde anlegen"). Mit `email` → eingeladenes Login-Konto (Invite-Mail),
|
|
21
|
+
ohne `email` → verwaltetes Konto (ohne Login). Partner/Agentur: Konto wird dem Betreuer zugeordnet,
|
|
22
|
+
Agentur-Kunden erhalten automatisch den Agentur-Plan (`agentur-kunde`/`billing_offline`). Antwort nennt die
|
|
23
|
+
neue Konto-ID (k-…) + den Hinweis, die erste Website per `site_deploy` mit `site="<k-id>:new"` zu importieren.
|
|
24
|
+
Schutz: Namens-/E-Mail-Dublette → Warnung mit vorhandener Konto-ID statt Doppelanlage (`override:true`
|
|
25
|
+
erzwingt die Namensdublette; eine vergebene E-Mail ist nicht erzwingbar), Rate-Limit 10 Konten/Stunde je Token.
|
|
26
|
+
Die Beschreibung lenkt den Assistenten dorthin, wenn es für einen Kunden noch KEIN Konto gibt (statt `site=new`).
|
|
27
|
+
|
|
6
28
|
## 0.9.2 – 2026-10-01
|
|
7
29
|
|
|
8
30
|
- **Pflicht-Marker in den Tool-Beschreibungen** (`site_deploy`, `site_legal_options`) + README: Rechtsseiten
|
package/README.md
CHANGED
|
@@ -82,6 +82,7 @@ sichern: `cp ~/.prontosite.json ~/.prontosite.json.bak`).
|
|
|
82
82
|
| Tool | Wirkung |
|
|
83
83
|
|------|---------|
|
|
84
84
|
| `sites_list` | Alle erreichbaren Websites (Slug, Plan, letzte Änderung, Publish-Bedarf). **Lesend.** |
|
|
85
|
+
| `account_create({ name, email?, plan?, note?, override? })` | **Nur mit Betreuer-Token.** Legt ein neues Kundenkonto an (Dashboard-Weg „Kunde anlegen"). Mit `email` → eingeladenes Login-Konto (Invite-Mail), ohne → verwaltetes Konto. Partner/Agentur: Konto wird dem Betreuer zugeordnet (Agentur-Kunden automatisch `agentur-kunde`). Antwort nennt die neue Konto-ID (k-…) → danach `site_deploy({ site: "<k-id>:new", zipPath })`. Namens-/E-Mail-Dublette → Warnung mit vorhandener k-ID (`override:true` erzwingt die Namensdublette). **Schreibend.** |
|
|
85
86
|
| `site_status({ site? })` | Plan, Slug, Live-URL, Publish-Bedarf. **Lesend.** |
|
|
86
87
|
| `site_export({ site?, which, outDir })` | ZIP (`published`\|`draft`\|`original`) lokal speichern. **Lesend.** |
|
|
87
88
|
| `site_deploy({ site?, zipPath, publish?, resetOverlay?, legal?, company?, siteOverride? })` | ZIP importieren, optional live; optional Firmendaten im selben Aufruf setzen. Beim lokalen Bauen Bausteine im HTML per `data-ps` markieren (`formular:kontakt`, `impressum`/`datenschutz`, `link-impressum`/`link-datenschutz`) → [Marker-Syntax](https://prontosite.io/docs/marker-shortcodes). **Schreibend.** |
|
|
@@ -142,6 +143,11 @@ Admin/Partner-Bereich (Panel „Betreuer-Token"). Config dann einfach:
|
|
|
142
143
|
zugeordnet ist – keine Config-Pflege). Website je Aufruf per Slug **oder stabiler Site-ID** angeben (kein
|
|
143
144
|
`"active"` – es sind mehrere Konten). Erst-Import: `site_deploy({ site: "new", customer: "k-…" })`.
|
|
144
145
|
|
|
146
|
+
**Neuen Kunden anlegen** (es gibt noch KEIN Konto): zuerst `account_create({ name, email? })` – das Konto wird
|
|
147
|
+
dem Betreuer zugeordnet (Agentur-Kunden automatisch `agentur-kunde`). Die Antwort nennt die Konto-ID (k-…);
|
|
148
|
+
danach die erste Website per `site_deploy({ site: "<k-id>:new", zipPath })` importieren. Also **nicht** `site=new`
|
|
149
|
+
raten, solange die Konto-ID unbekannt ist – erst `account_create`.
|
|
150
|
+
|
|
145
151
|
Sicherheit: der Zugriff wird bei JEDEM Aufruf serverseitig geprüft (`assertCanManage` – nur betreute Konten,
|
|
146
152
|
Rollenentzug wirkt sofort); nur Deploy/Status/Export/Veröffentlichen, kein Konto-/Zahlungszugriff; optionaler
|
|
147
153
|
Ablauf (Default 90 Tage) und optionale IP-Bindung; Widerruf sperrt alle betreuten Sites auf einmal.
|
package/api.mjs
CHANGED
|
@@ -159,6 +159,22 @@ export async function apiDeploy(cfg, { site, customer = null, slug: wishSlug = n
|
|
|
159
159
|
return out;
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
+
/** POST /api/account – Kundenkonto per BETREUER-Token anlegen (Dashboard-Weg „Kunde anlegen"). Mit email →
|
|
163
|
+
* eingeladenes Login-Konto (Invite-Mail), ohne email → verwaltetes Konto (ohne Login). Nutzt das Top-Level-
|
|
164
|
+
* Betreuer-Token (nicht die sites-Map – ein Betreuer-Token gilt konto-übergreifend). */
|
|
165
|
+
export async function apiAccountCreate(cfg, { name, email = null, plan = null, note = null, override = false } = {}, fetchImpl = fetch) {
|
|
166
|
+
if (!name || !String(name).trim()) throw new Error("name ist Pflicht (Anzeigename des Kunden).");
|
|
167
|
+
const token = needToken(cfg.token, "Betreuer-Token");
|
|
168
|
+
const body = { name: String(name).trim() };
|
|
169
|
+
if (email) body.email = String(email).trim();
|
|
170
|
+
if (plan) body.plan = String(plan).trim();
|
|
171
|
+
if (note) body.note = String(note).trim();
|
|
172
|
+
if (override === true) body.override = true;
|
|
173
|
+
const res = await fetchImpl(`${baseUrl(cfg)}/account`, {
|
|
174
|
+
method: "POST", headers: { ...authHeaders(token), "content-type": "application/json" }, body: JSON.stringify(body) });
|
|
175
|
+
return asJson(res);
|
|
176
|
+
}
|
|
177
|
+
|
|
162
178
|
/** POST /api/publish/<site> – erneut veröffentlichen (ohne ZIP). force=true = „trotzdem veröffentlichen"
|
|
163
179
|
* (auch ohne erkannte Änderung), analog zum Dashboard-Menüpunkt „Erneut veröffentlichen". */
|
|
164
180
|
export async function apiPublish(cfg, { site, force = false } = {}, fetchImpl = fetch) {
|
package/index.mjs
CHANGED
|
@@ -8,16 +8,18 @@
|
|
|
8
8
|
* Multi-Site (Betreuer): trägt die Config eine `sites`-Map, adressiert jedes Tool per `site`-Parameter die
|
|
9
9
|
* jeweilige Website (eigenes Token je Site). Arbeitsweise: EIN Chat je Kunde. `sites_list` zeigt alle Sites.
|
|
10
10
|
*/
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
import { realpathSync } from "node:fs";
|
|
11
13
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
12
14
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
13
15
|
import { z } from "zod";
|
|
14
|
-
import { loadConfig, apiStatus, apiExport, apiDeploy, apiPublish, sitesList, apiCompanyGet, apiCompanySet, apiLegalOptions, apiDomainStatus, apiDomainConnect, apiEmbeds, apiEmbedConsent, apiWidgets, apiWidgetSet } from "./api.mjs";
|
|
16
|
+
import { loadConfig, apiStatus, apiExport, apiDeploy, apiPublish, sitesList, apiAccountCreate, apiCompanyGet, apiCompanySet, apiLegalOptions, apiDomainStatus, apiDomainConnect, apiEmbeds, apiEmbedConsent, apiWidgets, apiWidgetSet } from "./api.mjs";
|
|
15
17
|
|
|
16
18
|
const cfg = loadConfig();
|
|
17
19
|
// Deutliche Startwarnung bei ambiger Konfiguration (Top-Level-Token NEBEN sites-Map). Nach stderr, damit
|
|
18
20
|
// es im MCP-Log/Terminal auffällt; die endgültige Auflösung (Betreuer-Token-Vorrang vs. Map) klärt sites_list.
|
|
19
21
|
for (const w of (cfg.warnings || [])) process.stderr.write("[prontosite-mcp] ⚠ " + w + "\n");
|
|
20
|
-
const server = new McpServer({ name: "prontosite", version: "0.
|
|
22
|
+
const server = new McpServer({ name: "prontosite", version: "0.10.0" });
|
|
21
23
|
const asText = obj => ({ content: [{ type: "text", text: JSON.stringify(obj, null, 2) }] });
|
|
22
24
|
const asError = e => ({ isError: true, content: [{ type: "text", text: "Fehler: " + (e?.message || String(e)) }] });
|
|
23
25
|
const SITE_DESC = "Website-Slug (z. B. 'mas-monti'). Ohne Angabe die Standard-Site der Config. Bei Betreuer-"
|
|
@@ -54,6 +56,29 @@ server.tool(
|
|
|
54
56
|
async () => { try { return asText(await sitesList(cfg)); } catch (e) { return asError(e); } }
|
|
55
57
|
);
|
|
56
58
|
|
|
59
|
+
server.tool(
|
|
60
|
+
"account_create",
|
|
61
|
+
"SCHREIBEND (nur mit Betreuer-Token: admin/partner/agentur): Legt ein NEUES Kundenkonto an – der Dashboard-"
|
|
62
|
+
+ "Weg „Kunde anlegen“. Nutze dieses Tool, BEVOR du eine Website importierst, wenn es für den Kunden noch "
|
|
63
|
+
+ "KEIN Konto gibt (z. B. sites_list zeigt den Kunden nicht, oder der Nutzer sagt „für Kunde X gibt es noch "
|
|
64
|
+
+ "kein Konto“). Erst Konto anlegen, dann mit der zurückgegebenen Konto-ID (k-…) per site_deploy und "
|
|
65
|
+
+ "site=\"<k-id>:new\" die erste Website importieren. Richte KEIN site=new/Erst-Import ein, solange die "
|
|
66
|
+
+ "Konto-ID unbekannt ist – dann zuerst dieses Tool. Mit email wird ein Login-Konto angelegt und eine "
|
|
67
|
+
+ "Einladungs-Mail verschickt; ohne email ein verwaltetes Konto (ohne Login, Betrieb über den Betreuer). "
|
|
68
|
+
+ "Partner/Agentur: das Konto wird DIR zugeordnet; Agentur-Kunden erhalten automatisch den Agentur-Plan "
|
|
69
|
+
+ "(Abrechnung über die Agentur). Schutz: bei gleichem Namen/gleicher E-Mail kommt eine Warnung mit der "
|
|
70
|
+
+ "bereits vorhandenen Konto-ID statt einer Doppelanlage – mit override:true trotzdem anlegen. "
|
|
71
|
+
+ "Bitte VOR dem Aufruf bestätigen lassen (es wird ggf. eine Mail an den Kunden gesendet).",
|
|
72
|
+
{ name: z.string().describe("Pflicht: Anzeigename des Kunden (z. B. Firmenname)."),
|
|
73
|
+
email: z.string().optional().describe("Optional: E-Mail des Kunden. Gesetzt → eingeladenes Login-Konto (Invite-Mail); weggelassen → verwaltetes Konto ohne Login."),
|
|
74
|
+
plan: z.enum(["free", "agentur-kunde"]).optional().describe("Optional. Standard richtet sich nach dem Betreuer-Konto (Agentur → agentur-kunde, sonst free). Nur angeben, wenn du den Standard bestätigen willst."),
|
|
75
|
+
note: z.string().optional().describe("Optionale interne Notiz – erscheint im Konto-Verlauf des neuen Kontos."),
|
|
76
|
+
override: z.boolean().default(false).describe("true = eine Namensdublette-Warnung übergehen und trotzdem ein weiteres Konto anlegen. Eine bereits vergebene E-Mail lässt sich NICHT erzwingen.") },
|
|
77
|
+
async ({ name, email, plan, note, override }) => {
|
|
78
|
+
try { return asText(await apiAccountCreate(cfg, { name, email, plan, note, override })); } catch (e) { return asError(e); }
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
|
|
57
82
|
server.tool(
|
|
58
83
|
"site_status",
|
|
59
84
|
"Status einer ProntoSite-Website: Plan, Slug, Live-URL, letzte Änderungen und offener Veröffentlichungs"
|
|
@@ -248,5 +273,13 @@ server.tool(
|
|
|
248
273
|
}
|
|
249
274
|
);
|
|
250
275
|
|
|
251
|
-
|
|
252
|
-
|
|
276
|
+
// Den stdio-Server NUR starten, wenn diese Datei direkt ausgeführt wird (als MCP-Server / bin).
|
|
277
|
+
// Beim bloßen Importieren (Smoke-Test / Tests) NICHT verbinden – sonst würde der Import auf stdin blockieren.
|
|
278
|
+
// So lädt der Import die Datei komplett (inkl. aller server.tool-Registrierungen → fängt Syntax-/Beschreibungs-
|
|
279
|
+
// fehler) ohne den Server zu starten.
|
|
280
|
+
let isMain = false;
|
|
281
|
+
try { isMain = !!process.argv[1] && realpathSync(process.argv[1]) === fileURLToPath(import.meta.url); } catch { /* argv[1] fehlt (node -e) → kein Main */ }
|
|
282
|
+
if (isMain) {
|
|
283
|
+
const transport = new StdioServerTransport();
|
|
284
|
+
await server.connect(transport);
|
|
285
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prontosite/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.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": {
|
|
7
7
|
"prontosite-mcp": "index.mjs"
|
|
8
8
|
},
|
|
9
9
|
"main": "index.mjs",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"check": "node --check index.mjs && node --check api.mjs",
|
|
12
|
+
"smoke": "node smoke.mjs",
|
|
13
|
+
"prepublishOnly": "npm run check && npm run smoke"
|
|
14
|
+
},
|
|
10
15
|
"files": [
|
|
11
16
|
"index.mjs",
|
|
12
17
|
"api.mjs",
|