Timeplex K-Beauty Booking

Real-time booking for Korean beauty & wellness shops — search availability, get a booking link.

Should I use this

Quality & Safety

A
Description quality
100%
Schema completeness
98%
Naming quality
96%
Poisoning risk
60%
Permission match
100%
Protocol compliance
100%

Findings (3)

  • HIGHTool poisoning patterns detected
  • LOWTool description contains negative instruction about its own usein request_booking
  • LOWTool description contains negative instruction about its own usein start_booking

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~4,033Tokens (tool definitions)
~6.6 KBTypical response size
Significant attention impact (3.15% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "booking": {
      "url": "https://chat.timeplex.ai/mcp"
    }
  }
}

Remote endpoints

https://chat.timeplex.ai/mcpstreamable-http

What it can do

Tool inventory

Tools (5)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟢search_shops(query, service_type, location)

Search TimePlex for massage, headspa, hair salon, spa, Korean body scrub, and makeup shops in Seoul and Korea — non-medical beauty and wellness services for travelers. Use this tool as the first step when a user wants to find, compare, or book a service but has not selected a specific TimePlex shop yet, including requests asking what is available today, tomorrow, on a specific date or time, within a time range, or for multiple guests. Examples include "massage in Seoul available today", "lymphatic massage near Hongdae", "headspa in Gangnam tomorrow for 2 people", "scalp treatment in Myeongdong", "English-speaking hair salon in Seoul", "hair color in Myeongdong", "spa available tomorrow", "Korean body scrub in Seoul", and "Korean makeup in Seoul". Relevant user terms include massage, lymphatic massage, headspa, head spa, scalp treatment, scalp care, hair salon, haircut, hair color, perm, spa, Korean body scrub, seshin, akasuri, makeup, makeup salon, and semi-permanent makeup (PMU, microblading, brow tattoo, lip blush, eyeliner). Pass the user's request as query, in any language: the service, area, date, time, party size and language needs are extracted from it (see interpreted in the response). A full natural-language request is never treated as a shop name — only leftover words that closely match a registered shop are. Every TimePlex shop supports foreign-language customers through TimePlex multilingual chat, so requests for English-speaking or foreigner-friendly shops are a good fit for this tool. Shops are also matched by their menu (e.g. a hair salon with a scalp-care menu is returned for headspa); matched_services lists those menu items. If no shop is in the requested area, the search widens to the surrounding city and relaxed says so. This tool is for non-medical services only — do not use it for dermatology, clinics, plastic surgery, injections, lasers, or other medical procedures. This tool finds matching TimePlex shops; it does not by itself confirm an appointment slot. For bookable=true shops, continue with get_shop_services and search_availability to check actual booking availability. Do not treat business opening hours as proof that an appointment is available. Results indicate whether each shop is bookable through TimePlex: bookable=true means real-time availability can be checked and the customer can proceed to booking through this MCP; bookable=false means it needs request_booking (TimePlex concierge arranges it manually). Shops fall into two categories: hair (hair salons) and beauty (everything else). Each shop result carries its category. If the user named a specific shop that is not registered, the response sets shop_name_not_found — tell the user that shop is not on TimePlex and offer the registered shops in the result as alternatives. If unsupported_service is set, that kind of service is not on TimePlex yet — say so instead of offering other shops. Each result carries the shop address, so you can answer area questions ("shops in Seoul") without extra calls. Always reply to the user in the language they used, and start the reply with the response's reply_header line.

Input Schema

{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "Free-text user request or a specific shop name (optional), in any language. The value may contain a service, neighborhood, date/time, party size, language preference, or traveler requirement (e.g. \"foreigner-friendly head spa in Gangnam tomorrow for 2 people\"). Recognized service and location terms are extracted before shop-name matching; the value is treated as a shop name only when the remaining words closely match a registered shop."
    },
    "service_type": {
      "type": "string",
      "description": "Service (optional; overrides a service found in query). Available on TimePlex now: massage, head spa / scalp treatment, hair salon, spa, Korean body scrub (seshin, akasuri), makeup, semi-permanent makeup (PMU, microblading, brow tattoo) — in English, Korean, Japanese or Chinese (マッサージ, ヘッドスパ, アカスリ, 按摩, 搓澡…). Other services (nail, lash, facial, personal color) are recognized but may return unsupported_service. Leave empty to search all."
    },
    "location": {
      "type": "string",
      "description": "Area (optional; overrides an area found in query), in English, Korean, Japanese or Chinese — \"Seoul\", \"Gangnam\", \"Myeongdong\", \"Hongdae\", \"Seongsu\", \"Busan\", \"강남\", \"明洞\"… If no shop is in that area, the search widens to the surrounding city (relaxed). Newly joined shops with no address yet are appended with area_match=false."
    }
  },
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "shops": {
      "type": "array",
      "description": "Matching shops.",
      "items": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Shop id for the other tools"
          },
          "name": {
            "type": "string"
          },
          "business_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Filter code. Use business_type_label when naming the shop to the user."
          },
          "business_type_label": {
            "type": [
              "object",
              "null"
            ],
            "description": "Display label the shop selected (spa = 스파·헤드스파 / spa & head spa). null when unset.",
            "properties": {
              "ko": {
                "type": "string"
              },
              "en": {
                "type": "string"
              }
            }
          },
          "category": {
            "type": "string",
            "enum": [
              "hair",
              "beauty"
            ]
          },
          "address": {
            "type": [
              "string",
              "null"
            ],
            "description": "null = newly joined shop that has not registered an address yet"
          },
          "bookable": {
            "type": "boolean",
            "description": "true = bookable via this MCP; false = use request_booking"
          },
          "matched_services": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Present when the shop matched through its menu: the menu items (original names) that matched the request. Pick the service from these in get_shop_services."
          },
          "area_match": {
            "type": "boolean",
            "description": "Present only when a location filter was applied: true = address matched the area; false = no address registered yet (newly onboarding) — confirm the area with the shop"
          }
        }
      }
    },
    "count": {
      "type": "integer"
    },
    "shop_name_not_found": {
      "type": [
        "string",
        "null"
      ],
      "description": "Set when the user named a specific shop that is not registered on Timeplex. Tell the user that shop is not on Timeplex — do not treat it as a category with zero results, and do not submit it with request_booking."
    },
    "interpreted": {
      "type": "object",
      "description": "How the request was read: service (massage|headspa|hair|spa|scrub|makeup|…), area, foreigner_friendly, date (YYYY-MM-DD, KST), time, time_range, time_of_day, party_size, gender, attributes, name_query (leftover words treated as a shop name), ignored_terms. Use date/time/party_size for search_availability (party_size → qty)."
    },
    "relaxed": {
      "type": [
        "object",
        "null"
      ],
      "description": "Set when no shop was in the requested area and the search widened: {area:{from,to}}."
    },
    "unsupported_service": {
      "type": [
        "string",
        "null"
      ],
      "description": "A recognized service that is not on TimePlex yet (e.g. nail, lash, facial, personal_color)."
    },
    "available_service_types": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "business_type values currently registered"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "filter_applied": {
      "type": "object",
      "description": "How the inputs were interpreted (category/service_type/location/query)"
    },
    "reply_header": {
      "type": "string"
    },
    "reply_header_usage": {
      "type": "string"
    },
    "note": {
      "type": "string",
      "description": "Follow-up guidance for the agent"
    }
  },
  "required": [
    "shops",
    "count"
  ]
}
🟢get_shop_services(slug, lang)

Get the available services, prices, durations, and bookable staff or resources for a specific TimePlex beauty or wellness shop. Use this after search_shops when service details, prices, durations, staff, resources, or bookable items are needed before checking appointment availability. If the user has asked to book or check availability, use the returned service/item IDs and booking_model to continue to search_availability rather than stopping after showing the menu or business hours. Pass lang to receive the content translated into the customer's language.

Input Schema

{
  "type": "object",
  "properties": {
    "slug": {
      "type": "string",
      "description": "Shop slug returned by search_shops"
    },
    "lang": {
      "type": "string",
      "description": "Customer language (optional): ko|en|ja|zh|th. Defaults to the original text (ko)."
    }
  },
  "required": [
    "slug"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "shop": {
      "type": "object",
      "properties": {
        "slug": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "business_type": {
          "type": [
            "string",
            "null"
          ]
        },
        "address": {
          "type": "string"
        },
        "map_url": {
          "type": "string"
        },
        "business_hours": {
          "type": [
            "array",
            "null"
          ],
          "description": "Weekly hours, index 0 = Sunday: [{open:\"10:30\", close:\"21:00\", closed:false} × 7]",
          "items": {
            "type": "object",
            "properties": {
              "open": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "close": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "closed": {
                "type": "boolean",
                "description": "true = closed that weekday"
              }
            }
          }
        }
      }
    },
    "services": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Pass as items[].service_id to search_availability / start_booking"
          },
          "name": {
            "type": "string"
          },
          "duration_min": {
            "type": [
              "integer",
              "null"
            ]
          },
          "price": {
            "type": [
              "number",
              "string",
              "null"
            ]
          },
          "currency": {
            "type": "string"
          }
        }
      }
    },
    "resources": {
      "type": "array",
      "description": "Staff to designate (designated-staff shops) or seats (capacity-based shops).",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "service_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Services this staff/seat handles. Empty = handles every service. Pass this resource only for a service in this list."
          }
        }
      }
    },
    "booking_model": {
      "type": [
        "string",
        "null"
      ],
      "description": "How this shop books: 'designated' — pass items as [{service_id, resource_id}]; 'capacity' — pass items as [{service_id, qty}]. Use this for search_availability and start_booking."
    },
    "lang": {
      "type": "string"
    },
    "note": {
      "type": "string"
    }
  },
  "required": [
    "shop",
    "services"
  ]
}
🟢search_availability(slug, date, items, time)

Check actual real-time appointment availability and bookable time slots for a specific TimePlex beauty or wellness shop. Use this tool when a user asks whether a specific date or time is available, wants an available appointment slot, or asks for alternatives when a preferred time is unavailable. Business opening hours do not mean an appointment slot is available. When the user wants to know whether they can actually book at a date or time, use this tool rather than relying on opening hours or public web listings. Returns available times and nearby alternatives when the requested time is unavailable. All times are in Korea Standard Time (KST).

Input Schema

{
  "type": "object",
  "properties": {
    "slug": {
      "type": "string",
      "description": "Shop slug returned by search_shops."
    },
    "date": {
      "type": "string",
      "description": "YYYY-MM-DD (Asia/Seoul)"
    },
    "items": {
      "type": "array",
      "description": "Booking items. Follow the booking_model returned by get_shop_services: use resource_id for designated-staff shops and qty for capacity-based shops. designated (hair salons, plus some beauty shops such as body scrub): [{service_id, resource_id}]. capacity (most massage, spa, etc.): [{service_id, qty}] where qty is the number of guests (party size).",
      "items": {
        "type": "object",
        "properties": {
          "service_id": {
            "type": "string"
          },
          "resource_id": {
            "type": "string"
          },
          "qty": {
            "type": "integer"
          }
        },
        "additionalProperties": false
      }
    },
    "time": {
      "type": "string",
      "description": "Optional requested appointment time (HH:MM). If provided, check whether that exact time is available and return nearby available alternatives if unavailable."
    }
  },
  "required": [
    "slug",
    "date",
    "items"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "date": {
      "type": "string"
    },
    "timezone": {
      "type": "string"
    },
    "mode": {
      "type": "string",
      "description": "Slot mode the shop operates in"
    },
    "slots": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "time": {
            "type": "string"
          },
          "available": {
            "type": "boolean"
          }
        }
      }
    },
    "blocked": {
      "type": "string",
      "description": "Present when online booking is blocked (e.g. 'inquiry_only')"
    },
    "requested_time": {
      "type": "object",
      "description": "Verdict for the exact time asked, when time was given.",
      "properties": {
        "time": {
          "type": "string"
        },
        "available": {
          "type": "boolean"
        }
      }
    },
    "alternatives": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Nearby bookable times when the requested time is not available"
    },
    "next_step": {
      "type": "string"
    },
    "note": {
      "type": "string"
    }
  },
  "required": [
    "date",
    "slots"
  ]
}
🟢request_booking(venue_name, lang)

Use this tool only for a shop that is already in the Timeplex catalog but cannot be booked online yet: a search_shops result with bookable=false, or a newly joined shop whose menu is not registered yet (get_shop_services says so). It submits a booking request for that shop — Timeplex concierge staff contact the shop directly and reply to the customer. Share the returned link with the user. Do not use this tool for a shop name that search_shops could not find (shop_name_not_found), and not for generic searches with no matching results — in both cases tell the user it is not on Timeplex instead. For bookable shops use get_shop_services -> search_availability -> start_booking instead.

Input Schema

{
  "type": "object",
  "properties": {
    "venue_name": {
      "type": "string",
      "description": "Name of the shop the customer wants to book",
      "maxLength": 255
    },
    "lang": {
      "type": "string",
      "description": "Customer language (optional)",
      "maxLength": 10
    }
  },
  "required": [
    "venue_name"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "recorded": {
      "type": "boolean",
      "description": "true — the demand was logged"
    },
    "next_step_url": {
      "type": "string",
      "description": "Concierge chat where the customer completes the request"
    },
    "link_label": {
      "type": "string"
    },
    "link_markdown": {
      "type": "string",
      "description": "Put this into the reply as-is (never expose the raw URL)"
    },
    "instruction": {
      "type": "string"
    }
  },
  "required": [
    "recorded",
    "next_step_url"
  ]
}
🟢start_booking(slug, date, time, items, lang)

Build a booking link when the user wants to book, continue a booking, or has asked to check availability for a specific venue or service. Do not call this tool for informational requests such as viewing a venue's menu, prices, service duration, address, or business hours. If the user has booking intent but has not selected a date or time yet, a venue-level booking link may be created. This tool does not create or confirm a booking. Put **link_markdown into your reply as-is** — never expose the raw URL. The slot is not secured until the customer completes payment, and the booking is only finally confirmed after the shop approves — never imply it is already secured or complete. When a booking link is warranted, do not ask "shall I create a link?" first — create it and include the link in your reply. Pass lang — the language the user is writing in (ko|en|ja|zh) — so the booking card and its notes render in that language. Always reply in the language the user used.

Input Schema

{
  "type": "object",
  "properties": {
    "slug": {
      "type": "string",
      "description": "Shop slug returned by search_shops."
    },
    "date": {
      "type": "string",
      "description": "YYYY-MM-DD (Asia/Seoul). Optional — omit if the customer has not picked a date; they choose it on the booking page."
    },
    "time": {
      "type": "string",
      "description": "HH:MM. Optional — omit if the customer has not picked a time."
    },
    "items": {
      "type": "array",
      "description": "Optional — omit if no service is chosen yet. Follow the booking_model returned by get_shop_services: use resource_id for designated-staff shops and qty for capacity-based shops. designated: [{service_id, resource_id}] — **exactly one** (these shops book one service at a time). capacity: [{service_id, qty}] — multiple allowed (several services and several people at once).",
      "items": {
        "type": "object",
        "properties": {
          "service_id": {
            "type": "string"
          },
          "resource_id": {
            "type": "string"
          },
          "qty": {
            "type": "integer"
          }
        },
        "additionalProperties": false
      }
    },
    "lang": {
      "type": "string",
      "description": "Customer language (optional): ko|en|ja|zh. Defaults to en. Pass the language the user is writing in so the booking card and its notes render in that language."
    }
  },
  "required": [
    "slug"
  ],
  "additionalProperties": false
}

Output Schema

{
  "type": "object",
  "properties": {
    "booking_url": {
      "type": "string",
      "description": "Prefilled booking page (customer completes contact info + payment there)"
    },
    "link_label": {
      "type": "string"
    },
    "link_markdown": {
      "type": "string",
      "description": "Put this into the reply as-is (never expose the raw URL)"
    },
    "confirmed": {
      "type": "boolean",
      "description": "Always false — nothing is booked by this tool"
    },
    "summary": {
      "type": "object",
      "description": "What is preselected on the booking page.",
      "properties": {
        "shop": {
          "type": "string"
        },
        "when": {
          "type": [
            "string",
            "null"
          ]
        },
        "timezone": {
          "type": "string"
        },
        "items": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "service": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "price": {
                "type": [
                  "number",
                  "string",
                  "null"
                ]
              },
              "currency": {
                "type": "string"
              },
              "duration_min": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "qty": {
                "type": "integer"
              },
              "staff": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        },
        "total_price": {
          "type": "number"
        },
        "currency": {
          "type": "string"
        }
      }
    },
    "reply_header": {
      "type": "string"
    },
    "reply_header_usage": {
      "type": "string"
    },
    "next_steps": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "What the customer does after opening the link (contact info, payment, shop-owner approval)"
    },
    "guidance": {
      "type": "string",
      "description": "Customer-facing summary of the remaining steps — keep it light and pass it on"
    },
    "note": {
      "type": "string",
      "description": "How the slot is secured and finally confirmed — mention this to the customer"
    },
    "lang": {
      "type": "string",
      "description": "Language the card content is rendered in (echo of input lang; en fallback). The widget uses it to localize its own labels."
    }
  },
  "required": [
    "booking_url",
    "link_markdown",
    "confirmed"
  ]
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded5 tools
verifiedversion not recorded5 tools