pilates_mcp
pilates_mcp
pilates_mcp 是一个面向普拉提中心宣传海报的本地优先 MCP 服务器。它创建可编辑的 HTML/CSS 海报源文件,将其存储在本地存档中,搜索并复用过往海报,记录设计反馈,并可通过无头 Chromium 渲染 PNG/PDF 产物。
第一阶段刻意不存储会员姓名、电话号码、课程表、健康数据、支付数据或其他会员个人信息。
项目结构
实现时该仓库为空,因此服务器以 TypeScript + Node.js MCP 服务器形式实现。
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
安装
npm install
npx playwright install chromium开发
npm run build
npm test
npm run devPILATES_MCP_DATA_DIR 可将存档指向另一个本地数据目录。若未设置,服务器使用 ./data。
Railway 部署
Railway 部署通过 railway.json 和 Dockerfile 配置。
生产容器使用官方 Playwright 镜像,以便 Chromium 运行时依赖可用于 PNG/PDF 渲染。Railway 启动 npm run start:railway,该命令暴露:
GET /health:部署健康检查GET /tools:用于部署检查的 MCP 工具摘要GET /schedule:轻量级 Excel 风格课程表工作区
stdio MCP 服务器仍可通过 npm run start 供以命令方式连接的 MCP 客户端使用。Railway 健康检查进程特意独立,因为 stdio MCP 不暴露 HTTP 端口。
为在 Railway 上实现持久的本地优先存档存储,请在 /data 挂载 Railway 卷,或将 PILATES_MCP_DATA_DIR 设置为其他持久路径。
MCP 客户端连接
将构建后的服务器作为 stdio MCP 命令使用:
{
"mcpServers": {
"pilates_mcp": {
"command": "node",
"args": ["G:/pilates_mcp/dist/src/server.js"],
"env": {
"PILATES_MCP_DATA_DIR": "G:/pilates_mcp/data"
}
}
}
}工具
海报工具:
get_center_profileupdate_center_profilesearch_postersget_postercreate_posterupdate_posterreuse_poster_templateimport_posterrender_posteradd_design_feedbackget_design_feedbackrecommend_poster_style
课程表工具:
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
海报创建流程
create_poster 读取中心档案,应用中心默认值,验证 PosterBrief,收集相关反馈,解析布局和主题,渲染静态 HTML/CSS,写入元数据/内容/源文件,并可选择渲染 PNG/PDF。
必需顺序为:
user request
-> center profile defaults
-> PosterBrief
-> validation
-> ask only missing questions
-> past posters and feedback
-> HTML/CSS
-> optional render
-> archive save生成前会验证海报简报中的必需决策:
eventNameprogramSeparationtablePreferencetableStyle(当需要或提供表格时)vatPolicy(当存在价格内容时)
服务器返回 valid: false、missing 和韩文 questions,而不是猜测缺失的活动名称、增值税政策或课程分离方式。
programSeparation 和 tableStyle 是独立的决策。例如,团体/私教产品可使用 programSeparation: "table" 搭配 tableStyle: "split" 来渲染独立的 GROUP/PRIVATE 表格区块。tablePreference 表示用户意图;layout 是最终的渲染器选择。
中心默认值可减少重复提问:
{
"posterDefaults": {
"programSeparation": "table",
"tablePreference": "required",
"tableStyle": "split",
"vatPolicy": "excluded"
}
}优先级为:当前请求和 PosterBrief,然后是中心档案默认值,最后是仅询问用户缺失值的验证响应。增值税从不推断。
示例
创建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
}反馈
反馈存储在 JSON 文件中,而非硬编码。create_poster 检索有效的全局和布局范围反馈,并将其作为 appliedFeedback 包含在结果中。
示例:
{
"scope": "table",
"text": "이벤트가는 정상가보다 확실히 강조."
}渲染
render_poster 使用禁用 JavaScript 的 Playwright Chromium。支持的尺寸:
instagram-portrait:1080 x 1350instagram-square:1080 x 1080story:1080 x 1920a4-portrait:A4 纵向
HTML/CSS 是事实来源。PNG/PDF 是可选的渲染产物。
课程表工作区
第二阶段添加了面向普拉提团体/私教课程表的本地优先课程表工作区。它不是 CRM。私教课程表可包含 displayName,仅用于网格显示和运营排位。
核心模型:
ScheduleSettings:周显示、营业/打烊时间、默认时段分钟数、节假日选项、区域设置、国家代码ScheduleTemplate:显式保存的每周团体/私教模板ScheduleSlot:与 Excel 单元格分离的中立领域时段ScheduleTemplateMapping:XLSX 工作表/表头/时间/日期列映射CenterClosure:中心特定的闭馆日期,与国家法定假日分开
set_schedule_slot 修改内存中的脏工作区。在调用 save_schedule 之前不会持久化。export_schedule 写入 XLSX,并在替换现有 XLSX 之前先进行备份。
现有 XLSX 文件由 inspect_schedule_file 和 import_schedule_file 处理。导入器捕获工作表名称、使用范围、日期列、时间列、列宽、行高以及可用的合并单元格。公式不会被执行。
节假日处理基于提供者。第二阶段包含一个带有基本 KR 节假日测试数据的本地提供者,日后可替换为外部提供者而无需更改领域模型。中心闭馆优先于公共假日,但已占用的时段不会被静默删除;会返回警告。
Railway 在 /schedule 提供轻量级 Excel 风格工作区,具有粘性表头、直接单元格编辑、删除/退格键以及可见的保存状态。MCP 仍是实际课程表操作的来源。
课程表示例
场景 A,在无文件时创建新的团体课程表:
{
"scheduleType": "group",
"settings": {
"weekDisplay": "mon-sat",
"openingTime": "09:00",
"closingTime": "21:00",
"defaultSlotMinutes": 60,
"autoHolidayMarking": true,
"locale": "ko-KR",
"countryCode": "KR"
}
}场景 B,导入现有 Excel 文件并生成下周课程表:
{ "filePath": "fixtures/group_schedule.xlsx", "scheduleType": "group" }{
"scheduleType": "group",
"weekStart": "2026-10-05",
"applyHolidays": true,
"applyCenterClosures": true
}场景 C,私教课程表操作:
{
"scheduleType": "private",
"dayOfWeek": "monday",
"startTime": "19:00",
"displayName": "김OO"
}场景 D,团体课程表海报:
{
"scheduleType": "group",
"weekStart": "2026-10-05",
"title": "9월 그룹레슨 시간표",
"render": { "png": true, "pdf": true, "size": "instagram-portrait" }
}安全与隐私
存档使用生成的海报 ID,并在文件访问前验证海报 ID。检查存档相对导入以阻止 ../ 遍历和根目录逃逸。生成的海报 HTML 是静态的,用户文本经过 HTML 转义,远程脚本不属于模板的一部分。渲染会禁用 JavaScript。
第一阶段排除会员管理、预约、支付、短信、Instagram 发布、StudioMate 集成、外部设计抓取、图像生成 AI、云数据库要求和 SaaS 认证。
第二阶段仅允许 displayName 作为与个人相关的课程表显示数据。它不会创建电话、电子邮件、地址、出生日期、性别、健康状况、病史、支付、会员资格、咨询、出勤档案或营销同意等字段。姓名不用于画像分析、数据分析、海报反馈、营销或推荐。
第二阶段仍排除 StudioMate 集成、StudioMate 抓取、Chrome 扩展自动化、会员 CRM、联系人管理、支付管理、出勤分析、会员偏好画像、自动预约确认、短信、KakaoTalk、Instagram 发布、工资单、结算以及复杂 ERP 功能。
扩展点
服务/仓库分离为未来的语义搜索或其他索引保留了空间。外部设计引用日后可在提供者接口之后添加,例如:
interface DesignReferenceProvider {
search(query: string): Promise<DesignReference[]>;
}第一阶段不实现抓取或复制外部模板。
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