Skip to main content
Glama

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 dev

PILATES_MCP_DATA_DIR 可将存档指向另一个本地数据目录。若未设置,服务器使用 ./data

Railway 部署

Railway 部署通过 railway.jsonDockerfile 配置。

生产容器使用官方 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_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

课程表工具:

  • 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

海报创建流程

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

生成前会验证海报简报中的必需决策:

  • eventName

  • programSeparation

  • tablePreference

  • tableStyle(当需要或提供表格时)

  • vatPolicy(当存在价格内容时)

服务器返回 valid: falsemissing 和韩文 questions,而不是猜测缺失的活动名称、增值税政策或课程分离方式。

programSeparationtableStyle 是独立的决策。例如,团体/私教产品可使用 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 1350

  • instagram-square:1080 x 1080

  • story:1080 x 1920

  • a4-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_fileimport_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[]>;
}

第一阶段不实现抓取或复制外部模板。

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