pilates_mcp
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 chromiumEntwicklung
npm run build
npm test
npm run devPILATES_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 BereitstellungGET /tools: MCP-Toolübersicht zur BereitstellungsprüfungGET /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_profileupdate_center_profilesearch_postersget_postercreate_posterupdate_posterreuse_poster_templateimport_posterrender_posteradd_design_feedbackget_design_feedbackrecommend_poster_style
Zeitplan-Tools:
get_schedule_settingsupdate_schedule_settingsinspect_schedule_fileimport_schedule_filecreate_schedule_templateget_schedulegenerate_weekly_scheduleset_schedule_slotclear_schedule_slotfind_available_slotsvalidate_scheduleadd_center_closureremove_center_closureget_center_closuressave_scheduleexport_schedulecreate_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 saveErforderliche Plakat-Brief-Entscheidungen werden vor der Generierung validiert:
eventNameprogramSeparationtablePreferencetableStyle, wenn eine Tabelle erforderlich oder bereitgestellt istvatPolicy, 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 1350instagram-square: 1080 x 1080story: 1080 x 1920a4-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ändercodeScheduleTemplate: explizit gespeicherte wöchentliche Gruppen-/PrivatvorlageScheduleSlot: neutraler Domänen-Slot, getrennt von Excel-ZellenScheduleTemplateMapping: XLSX-Arbeitsblatt-/Kopf-/Zeit-/Tages-SpaltenzuordnungCenterClosure: 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.
Maintenance
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
- AlicenseAqualityDmaintenanceMCP server that turns articles, transcripts, and markdown into LinkedIn carousel PDFs, Instagram PNGs, and Threads PNGs. Content in, slides out. No web UI, no cloud service.51MIT
- AlicenseNot gradedqualityBmaintenanceLocal-first MCP server for research on AI-assisted browsing of a user-owned professional-network account (e.g., LinkedIn), providing read-focused tools such as profile, company, search, and feed reads.MIT
- AlicenseBqualityAmaintenanceLocal-first MCP server that transforms civil case PDFs into queryable cases with structural provenance, evidence IDs, and page-level verification for drafting and factual review.22Apache 2.0
- AlicenseNot gradedqualityBmaintenanceLocal-first personal productivity MCP server bundling email, calendar, messaging, search, and image generation tools with BYOK and no cloud dependency.50MIT
Related MCP Connectors
WordPress MCP server: publish posts, AI images, SEO and full site management, self-hosted
MCP server for Zooza — class scheduling, attendance, and booking for activity businesses.
Private-by-default, local-first memory/context/task orchestrator for MCP apps and agents.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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