mcpField
E
Easy!Appointments

Easy!Appointments

远程服务
ea-mcp-demo.qiyuanlabs.ai生产力01 周前更新

关于 Easy!Appointments

Easy!Appointments MCP 服务让预约系统运营人员通过 AI 助手查询服务、客户和空闲时段,并管理预约。OAuth 登录、按连接设置只读或前台权限,所有更改均需先预览再确认。

主要功能

  1. 01查询服务、客户和预约
  2. 02按服务及时间筛选空闲时段
  3. 03创建、改期和取消预约
  4. 04按连接授予只读或前台权限
  5. 05更改需预览、签名令牌和幂等键
  6. 06记录并导出脱敏调用日志

适用场景

  1. 01为客户查找合适的预约时段
  2. 02登记新预约或调整现有预约
  3. 03查看客户的预约记录
  4. 04审查并导出前台操作日志

MCP 相关

作为远程 MCP 服务,通过 OAuth 向 AI 客户端提供 Easy!Appointments 查询和预约管理工具。写入操作须以同一人员和客户端提交匹配预览的确认令牌。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://ea-mcp-demo.qiyuanlabs.ai/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

详细介绍

Easy!Appointments MCP 服务

一个远程 MCP 服务,可让 Claude、ChatGPT 和其他 AI 助手为 Easy!Appointments 预约系统处理前台事务:查找空闲时段、查询客户,以及预约、改期或取消预约。

它面向运营预约系统的人员,而不仅仅是开发者:

  • 使用 OAuth 登录。 员工使用自己的账号将 AI 助手连接到系统。Easy!Appointments API 令牌不会离开服务器。
  • 每个连接有两个访问级别。 只读权限可以查看服务、空闲时段、客户和预约。前台权限还可以预约、改期和取消。管理员会为每个人设置权限上限。
  • 未经预览,不会进行任何更改。 每项更改都需要两步调用:先预览,由助手展示给用户;然后确认调用,并附带预览的签名 confirmation_token 和幂等键。与预览不匹配的确认会被拒绝,重试请求也绝不会重复预约。
  • 调用日志。 每次工具调用都会记录,并屏蔽个人详细信息,同时记录发出的 Easy!Appointments 请求和耗时。员工可以查看日志、将其导出为 CSV,并断开任何助手的连接。
  • 避免给 Easy!Appointments 增加负担。 API 每两分钟允许来自每个 IP 的 100 次请求。该服务会缓存目录和空闲时段,限制单次搜索涵盖的天数,并为每个预约系统共用一个请求预算(EA_REQUEST_BUDGET,默认为每两分钟 90 次),避免多个助手合计请求过多,导致系统被锁定。

本项目与 Easy!Appointments 无关联,也未获其认可。Easy!Appointments 是其所有者的商标。

工具

工具访问权限功能
list_services只读查看服务的时长、价格和提供服务的人员,以及每位服务提供者的时区
find_open_slots只读查找某项服务未来最多 14 天内的可预约开始时间,可指定一位或所有服务提供者,并按上午、下午或晚上筛选
find_customer只读按姓名、电子邮件或电话号码查找客户
list_appointments只读查看某位客户、某位服务提供者或某个日期范围内的预约
book_appointment前台为现有客户或新客户预约
reschedule_appointment前台将预约改到新的时间或服务提供者
cancel_appointment前台取消未来的预约

通过 API 进行的每项更改,Easy!Appointments 都会照常发送确认、更改和取消邮件。

要求

  • Easy!Appointments 1.5 或更高版本,并启用 API(Settings > Integrations > API:设置 API 令牌)。已在 1.6.1 上测试。
  • PHP 8.3 或更高版本,或 Docker。
  • 生产环境中使用 HTTPS。AI 客户端不会连接互联网上的纯 HTTP 服务器。

在本地运行演示

compose 文件会启动 Easy!Appointments 1.6.1、邮件接收器和此服务,然后为一家虚构的理疗诊所填充服务、服务提供者、客户和两周的预约数据。

cp .env.docker.example .env.docker
# Set APP_KEY (see the comment in the file) and EA_API_TOKEN (any long random string)
docker compose up -d --build
sh demo/setup.sh

然后:

若要在没有 AI 客户端的情况下检查完整流程,请运行端到端脚本。该脚本会注册 OAuth 客户端、登录、选择访问级别并调用每个工具,其中包括实际创建一项预约,然后将其改期并取消:

php demo/e2e.php http://localhost:8000 [email protected] demo-password-1 front_desk
php demo/e2e.php http://localhost:8000 [email protected] demo-password-1 read

若要通过 HTTPS 将演示部署到公共服务器,请参阅 docs/deploy-demo.md。

为实际预约系统安装

使用 Docker:

docker run -d --name ea-mcp \
  -e APP_KEY=base64:... \
  -e APP_URL=https://mcp.example.com \
  -e TRUSTED_PROXIES=10.0.0.5 \
  -v ea-mcp-data:/data/app \
  -p 127.0.0.1:8080:8080 \
  ea-mcp-server

将其置于 HTTPS 负载均衡器或反向代理之后,或者设置 SERVER_NAME=mcp.example.com 并发布 80 和 443 端口,让内置 Caddy 获取证书。

TRUSTED_PROXIES 决定信任谁提供的 X-Forwarded-For 标头,速率限制按客户端 IP 计算。仅将其设为代理的地址,并且只将 8080 端口发布给该代理(如果代理运行在同一主机上,则发布给 127.0.0.1)。如果端口可被直接访问,切勿使用 *,否则任何人都可以指定自己的 IP,绕过速率限制。由内置 Caddy 处理 HTTPS 时,请勿设置此项。在第二个容器中使用同一镜像运行 php artisan schedule:work,以便每天清理旧日志和过期令牌。

不使用 Docker 时,它是一个标准的 Laravel 13 应用:运行 composer install --no-dev,将 .env.example 复制为 .env,运行 php artisan key:generate、php artisan passport:keys 和 php artisan migrate,并将 Web 服务器指向 public/。

然后连接预约系统并添加员工:

php artisan ea:connect "Maple Street Physio" https://booking.example.com   # asks for the API token
php artisan ea:user [email protected] --name="Anna" --level=front_desk       # asks for a password

--level 是此人可以授予助手的最高级别。每位助手的具体级别仍由他们在授权页面上选择。

如果 ea:connect 使用有效令牌却收到 401,说明 Web 服务器没有将 Authorization 标头传递给 PHP。使用 PHP-FPM 的 Apache 环境中,请在 Easy!Appointments 虚拟主机配置中添加 SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1。

连接 AI 助手

将 https://your-server/mcp 添加为自定义连接器(Claude:Settings > Connectors;ChatGPT:在开发者模式下添加工作区连接器)。客户端会自行注册、打开登录页面,然后由用户选择 只读 或 前台。用户可以随时在 /dashboard 上更改或移除此设置。

安全模型

  • Easy!Appointments API 令牌具有管理员级别权限,因此会加密存储在此服务器上,绝不会发送给客户端。每个人都使用自己的账户登录,并获得一个仅在此处有效的短期令牌(有效期为 1 小时,可刷新,最长 30 天)。
  • 登录前,initialize 和 tools/list 无需令牌即可响应,以便客户端显示此服务提供的内容。没有有效令牌的任何 tools/call(以及其他所有请求)都会收到带有 WWW-Authenticate 标头的 401 响应,该标头指向 OAuth 元数据,这会在 Claude 和其他客户端中启动登录流程。登录后,连接无法使用的工具不会列出;即使调用,也会被拒绝。
  • 写入操作需要通过第二次调用确认。确认请求必须携带针对完全相同参数的预览所返回的 confirmation_token,并且由同一人和助手在 10 分钟内(MCP_CONFIRMATION_MINUTES)发起,同时还必须提供幂等键。该键会在写入任何内容之前被占用,因此使用同一个键并行重试只会预订一次。
  • Easy!Appointments 在 API 创建或移动预订时不会检查可用性。因此,每次确认都会锁定该服务提供者当天的时段,在锁内重新检查未经缓存的时段,之后才进行写入。使用不同键确认同一时段的两次请求中,只有一次会完成预订;另一请求会被拒绝,并返回最近的空闲时段。
  • 如果 Easy!Appointments 的响应丢失,或返回服务器错误,该键仍会保持占用状态,并会告知助手改用 list_appointments 检查,而不是盲目重试。一旦 Easy!Appointments 确认写入成功,此后发生的任何事情(例如读取姓名)都无法将其转为错误或撤销操作。
  • 时间会按照每位服务提供者自己的时区读取和写入,与 Easy!Appointments 中的存储方式一致;每个结果都会说明使用的时区。
  • 客户端注册开放,符合 MCP 的预期,但受到限制:重定向 URI 必须使用 https(或回环地址上的 http),且不得包含片段或用户信息;客户端注册按 IP 限流(MCP_REGISTRATIONS_PER_HOUR,每小时 10 次);从未使用的客户端会在一天后删除,已使用过但连续 90 天未使用的客户端也会删除。
  • 同意页面会将客户端名称标记为未经验证(任何应用都可以自行选择名称),显示此人将被发送到的主机,并在该主机不是已知 AI 助手时发出警告(MCP_KNOWN_CLIENT_HOSTS)。
  • 调用日志中的姓名、电子邮件、电话号码、地址、备注和搜索文本都会被屏蔽。Easy!Appointments 错误消息中回显客户记录的内容会被移除,错误中残留的任何电子邮件地址也会被屏蔽,然后才会显示给助手、写入调用日志或应用日志。
  • 登录尝试按 IP 限流,并对每个账户单独限流,因此即使通过多个 IP 分散猜测,也仍会触发限制(MCP_LOGIN_ATTEMPTS_PER_ACCOUNT,每 10 分钟 10 次)。DEMO_EMAIL 中设置的公开演示账户不受账户级限制,因为其密码已公开,限制只会让陌生人锁定该账户。只要 APP_URL 使用 https,会话 Cookie 就仅限 HTTPS 使用。
  • 为新客户创建预订时,会在开始前为所有请求预留额度;如果 Easy!Appointments 随后明确拒绝预订(返回 4xx),则会删除创建的客户。若未收到响应或发生服务器错误,预订可能已经存在,因此客户会保留,并会告知助手使用 list_appointments 检查。
  • .env.example 中设置了 APP_ENV=production 和 APP_DEBUG=false。ea:connect 会通过提示输入或从 EA_API_TOKEN 读取 API 令牌,因此令牌不会出现在 Shell 历史记录或进程列表中。
  • 默认保留日志 90 天(MCP_LOG_RETENTION_DAYS)。

已知限制

  • Easy!Appointments API 无法在忽略正在移动的预约的情况下检查可用时间,因此,如果改期后的时间与预约当前时间重叠,系统会拒绝操作并说明原因。遇到这种情况,请先取消再重新预约。
  • 在 Easy!Appointments 中取消预约会将其删除;API 不支持软取消。
  • 时段锁仅覆盖通过此服务进行的更改。如果有人同时直接在 Easy!Appointments 中预约同一时段,仍可能导致重复预约,因为其 API 无法预留时段。
  • Easy!Appointments 不会存储请求所用的时区,因此,提供者的时区日后发生变化时,其现有预约仍会保持在相同的本地时钟时间。
  • 一个服务可以关联多个 Easy!Appointments 实例,每个账户对应一个实例。没有自助注册功能;管理员可以使用 ea:user 添加人员。

开发

composer install
cp .env.example .env && sed -i 's/^APP_ENV=production/APP_ENV=local/' .env
php artisan key:generate && php artisan passport:keys && php artisan migrate
php artisan test
vendor/bin/pint

测试使用 Easy!Appointments API 的内存模拟实现(tests/Support/FakeEasyAppointments.php)。demo/e2e.php 使用真实实例运行。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。