Skip to main content
Glama

pilates_mcp

pilates_mcp ist ein lokaler MCP-Server für Werbeplakate von Pilates-Studios. Er erstellt bearbeitbare HTML/CSS-Plakatquellen, speichert sie in einem lokalen Archiv, durchsucht und verwendet frühere Plakate wieder, erfasst Design-Feedback und kann PNG/PDF-Artefakte mit headless Chromium rendern.

Phase 1 speichert bewusst keine Mitgliedernamen, Telefonnummern, Zeitpläne, Gesundheitsdaten, Zahlungsdaten oder andere persönliche Informationen von Mitgliedern.

Projektstruktur

Dieses Repository war zum Zeitpunkt der Implementierung leer, daher ist der Server als TypeScript- und Node.js-MCP-Server implementiert.

src/
  server.ts        MCP stdio JSON-RPC transport and tool dispatch
  service.ts       poster workflow orchestration
  repository.ts    local poster archive search/read/write
  renderer.ts      Playwright PNG/PDF renderer
  templates.ts     HTML/CSS template layer
  feedback.ts      design feedback storage
  profile.ts       center profile storage
  themes.ts        design token presets
  types.ts         domain types
data/
  posters/YYYY/<poster-id>/
    poster.html
    poster.css
    metadata.json
    content.json
    preview.png    optional
    poster.pdf     optional
    revisions/     update backups
  feedback/
    global.json
    table.json
    standard.json
    poster-<poster-id>.json
  config/
    center-profile.json
  schedules/
    settings.json
    center-closures.json
    group/
      template.json
      group_schedule.xlsx
      revisions/
    private/
      template.json
      private_schedule.xlsx
      revisions/

Related MCP server: Networking MCP

Installation

npm install
npx playwright install chromium

Entwicklung

npm run build
npm test
npm run dev

PILATES_MCP_DATA_DIR kann das Archiv auf ein anderes lokales Datenverzeichnis verweisen. Wenn nicht gesetzt, verwendet der Server ./data.

Railway-Bereitstellung

Die Railway-Bereitstellung ist mit railway.json und Dockerfile konfiguriert.

Der Produktionscontainer verwendet das offizielle Playwright-Image, sodass Chromium-Laufzeitabhängigkeiten für das PNG/PDF-Rendering verfügbar sind. Railway startet npm run start:railway, das Folgendes bereitstellt:

  • GET /health: Healthcheck für die Bereitstellung

  • GET /tools: MCP-Toolübersicht zur Bereitstellungsprüfung

  • GET /schedule: Leichtgewichtiger Excel-ähnlicher Zeitplan-Arbeitsbereich

Der stdio-MCP-Server bleibt über npm run start für MCP-Clients verfügbar, die per Befehl verbinden. Der Railway-Health-Prozess ist bewusst getrennt, da stdio-MCP keinen HTTP-Port bereitstellt.

Für die dauerhafte lokale Archivspeicherung auf Railway mounten Sie ein Railway-Volume unter /data oder setzen Sie PILATES_MCP_DATA_DIR auf einen anderen persistenten Pfad.

MCP-Client-Verbindung

Verwenden Sie den gebauten Server als stdio-MCP-Befehl:

{
  "mcpServers": {
    "pilates_mcp": {
      "command": "node",
      "args": ["G:/pilates_mcp/dist/src/server.js"],
      "env": {
        "PILATES_MCP_DATA_DIR": "G:/pilates_mcp/data"
      }
    }
  }
}

Tools

Plakat-Tools:

  • get_center_profile

  • update_center_profile

  • search_posters

  • get_poster

  • create_poster

  • update_poster

  • reuse_poster_template

  • import_poster

  • render_poster

  • add_design_feedback

  • get_design_feedback

  • recommend_poster_style

Zeitplan-Tools:

  • get_schedule_settings

  • update_schedule_settings

  • inspect_schedule_file

  • import_schedule_file

  • create_schedule_template

  • get_schedule

  • generate_weekly_schedule

  • set_schedule_slot

  • clear_schedule_slot

  • find_available_slots

  • validate_schedule

  • add_center_closure

  • remove_center_closure

  • get_center_closures

  • save_schedule

  • export_schedule

  • create_schedule_poster

Plakat-Erstellungsablauf

create_poster liest das Center-Profil, wendet Center-Standardwerte an, validiert den PosterBrief, sammelt relevantes Feedback, löst Layout und Theme auf, rendert statisches HTML/CSS, schreibt Metadaten/Inhalt/Quelldateien und rendert optional PNG/PDF.

Die erforderliche Reihenfolge ist:

user request
-> center profile defaults
-> PosterBrief
-> validation
-> ask only missing questions
-> past posters and feedback
-> HTML/CSS
-> optional render
-> archive save

Erforderliche Plakat-Brief-Entscheidungen werden vor der Generierung validiert:

  • eventName

  • programSeparation

  • tablePreference

  • tableStyle, wenn eine Tabelle erforderlich oder bereitgestellt ist

  • vatPolicy, wenn Preisinhalt vorhanden ist

Der Server gibt valid: false, missing und koreanische questions zurück, anstatt fehlende Veranstaltungsnamen, MwSt-Politik oder Programmtrennung zu erraten.

programSeparation und tableStyle sind separate Entscheidungen. Beispielsweise können Gruppen-/Privatprodukte mit programSeparation: "table" und tableStyle: "split" verwendet werden, um separate GROUP/PRIVATE-Tabellenblöcke zu rendern. tablePreference stellt die Benutzerabsicht dar; layout ist die endgültige Renderer-Wahl.

Center-Standardwerte können wiederholte Fragen reduzieren:

{
  "posterDefaults": {
    "programSeparation": "table",
    "tablePreference": "required",
    "tableStyle": "split",
    "vatPolicy": "excluded"
  }
}

Priorität ist: aktuelle Anfrage und PosterBrief, dann Center-Profil-Standardwerte, dann eine Validierungsantwort, die den Benutzer nur nach fehlenden Werten fragt. MwSt wird nie abgeleitet.

Beispiele

8월 회원권 가격표 포스터 생성

{
  "title": "8월 회원권 이벤트",
  "purpose": "event",
  "brief": {
    "eventName": "8월 회원권 이벤트",
    "programCategories": ["private", "duet"],
    "programSeparation": "table",
    "tablePreference": "required",
    "tableStyle": "comparison",
    "vatPolicy": "excluded"
  },
  "content": {
    "subtitle": "이번 달 특별 혜택",
    "badge": "8월 EVENT",
    "table": {
      "columns": ["상품", "정상가", "이벤트가"],
      "rows": [
        ["1:1 개인레슨 10회", "800,000원", "650,000원"],
        ["듀엣레슨 10회", "500,000원", "390,000원"]
      ],
      "highlightColumn": 2
    },
    "footer": "선착순 마감"
  },
  "style": "premium",
  "render": { "png": true, "pdf": true, "size": "instagram-portrait" }
}

작년 9월 포스터 틀 재사용

{
  "sourcePosterId": "poster_20250901_ab12cd34",
  "title": "2026년 9월 신규회원 이벤트",
  "brief": {
    "eventName": "9월 신규회원 이벤트",
    "vatPolicy": "excluded"
  },
  "content": {
    "subtitle": "올해 가격으로 업데이트",
    "table": {
      "columns": ["상품", "정상가", "이벤트가"],
      "rows": [["1:1 개인레슨 10회", "820,000원", "670,000원"]],
      "highlightColumn": 2
    }
  }
}

최근 1년 기록 기반 스타일 추천

{
  "purpose": "event",
  "month": 9,
  "recentMonths": 12
}

Feedback

Feedback wird in JSON-Dateien gespeichert, nicht hartcodiert. create_poster ruft aktives globales und layoutbezogenes Feedback ab und nimmt es als appliedFeedback in das Ergebnis auf.

Beispiel:

{
  "scope": "table",
  "text": "이벤트가는 정상가보다 확실히 강조."
}

Rendering

render_poster verwendet Playwright Chromium mit deaktiviertem JavaScript. Unterstützte Größen:

  • instagram-portrait: 1080 x 1350

  • instagram-square: 1080 x 1080

  • story: 1080 x 1920

  • a4-portrait: A4-Hochformat

HTML/CSS sind die Quelle der Wahrheit. PNG/PDF sind optionale gerenderte Artefakte.

Zeitplan-Arbeitsbereich

Phase 2 fügt einen lokalen Zeitplan-Arbeitsbereich für Pilates-Gruppen-/Privatstundenpläne hinzu. Es ist kein CRM. Private Zeitpläne dürfen displayName nur für die Rasteranzeige und die operative Platzierung enthalten.

Kernmodell:

  • ScheduleSettings: Wochenanzeige, Öffnungs-/Schließzeit, Standard-Slot-Minuten, Feiertagsoption, Gebietsschema, Ländercode

  • ScheduleTemplate: explizit gespeicherte wöchentliche Gruppen-/Privatvorlage

  • ScheduleSlot: neutraler Domänen-Slot, getrennt von Excel-Zellen

  • ScheduleTemplateMapping: XLSX-Arbeitsblatt-/Kopf-/Zeit-/Tages-Spaltenzuordnung

  • CenterClosure: centerspezifische geschlossene Daten, getrennt von nationalen Feiertagen

set_schedule_slot ändert einen In-Memory-Dirty-Arbeitsbereich. Es wird erst mit save_schedule persistiert. export_schedule schreibt XLSX und sichert eine vorhandene XLSX-Datei, bevor sie ersetzt wird.

Vorhandene XLSX-Dateien werden von inspect_schedule_file und import_schedule_file verarbeitet. Der Importeur erfasst Arbeitsblattname, verwendeten Bereich, Tages-Spalten, Zeitspalte, Spaltenbreiten, Zeilenhöhen und Zusammenführungen, wo verfügbar. Formeln werden nicht ausgeführt.

Die Feiertagsbehandlung ist providerbasiert. Phase 2 enthält einen lokalen Provider mit grundlegenden KR-Feiertags-Fixtures und kann später durch einen externen Provider ersetzt werden, ohne das Domänenmodell zu ändern. Center-Schließungen haben Priorität vor öffentlichen Feiertagen, aber belegte Slots werden nicht stillschweigend gelöscht; Warnungen werden zurückgegeben.

Railway bietet einen leichten Excel-ähnlichen Arbeitsbereich unter /schedule mit fixierten Kopfzeilen, direkter Zellbearbeitung, Löschen/Rücktaste und sichtbarem Speicherstatus. MCP bleibt die Quelle für tatsächliche Zeitplanoperationen.

Zeitplan-Beispiele

Szenario A, einen neuen Gruppenstundenplan erstellen, wenn keine Datei vorhanden ist:

{
  "scheduleType": "group",
  "settings": {
    "weekDisplay": "mon-sat",
    "openingTime": "09:00",
    "closingTime": "21:00",
    "defaultSlotMinutes": 60,
    "autoHolidayMarking": true,
    "locale": "ko-KR",
    "countryCode": "KR"
  }
}

Szenario B, eine vorhandene Excel-Datei importieren und die nächste Woche generieren:

{ "filePath": "fixtures/group_schedule.xlsx", "scheduleType": "group" }
{
  "scheduleType": "group",
  "weekStart": "2026-10-05",
  "applyHolidays": true,
  "applyCenterClosures": true
}

Szenario C, private Zeitplanoperation:

{
  "scheduleType": "private",
  "dayOfWeek": "monday",
  "startTime": "19:00",
  "displayName": "김OO"
}

Szenario D, Gruppenstundenplan-Plakat:

{
  "scheduleType": "group",
  "weekStart": "2026-10-05",
  "title": "9월 그룹레슨 시간표",
  "render": { "png": true, "pdf": true, "size": "instagram-portrait" }
}

Sicherheit und Datenschutz

Das Archiv verwendet generierte Plakat-IDs und validiert Plakat-IDs vor dem Dateizugriff. Archivrelative Importe werden geprüft, um ../-Traversal und Root-Escape zu blockieren. Generiertes Plakat-HTML ist statisch, Benutzertext ist HTML-escaped, und Remote-Skripte sind nicht Teil der Vorlage. Rendering deaktiviert JavaScript.

Phase 1 schließt Mitgliederverwaltung, Reservierungen, Zahlungen, SMS, Instagram-Posting, StudioMate-Integration, externes Design-Scraping, KI-Bildgenerierung, Cloud-DB-Anforderungen und SaaS-Authentifizierung aus.

Phase 2 erlaubt nur displayName als personenbezogene Zeitplan-Anzeigedaten. Es erstellt keine Felder für Telefon, E-Mail, Adresse, Geburtsdatum, Geschlecht, Gesundheitszustand, Krankengeschichte, Zahlung, Mitgliedschaft, Beratung, Anwesenheitsprofil oder Marketing-Einwilligung. Namen werden nicht für Profiling, Analysen, Plakat-Feedback, Marketing oder Empfehlungen verwendet.

Phase 2 schließt weiterhin StudioMate-Integration, StudioMate-Scraping, Chrome-Erweiterungsautomatisierung, Mitglieder-CRM, Kontaktverwaltung, Zahlungsverwaltung, Anwesenheitsanalyse, Mitgliederpräferenz-Profiling, automatische Buchungsbestätigung, SMS, KakaoTalk, Instagram-Posting, Gehaltsabrechnung, Abrechnung und komplexe ERP-Funktionen aus.

Erweiterungspunkte

Die Service-/Repository-Trennung lässt Raum für zukünftige semantische Suche oder einen anderen Index. Externe Designreferenzen können später hinter einer Provider-Schnittstelle wie folgt hinzugefügt werden:

interface DesignReferenceProvider {
  search(query: string): Promise<DesignReference[]>;
}

Phase 1 implementiert kein Scraping oder Kopieren externer Vorlagen.

Install Server
F
license - not found
B
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sebit-provider/pilates_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server