io.github.topness-msft/salonrunner-mcp

السجل الرسمي الألعاب والرياضة والترفيه

Self-hosted MCP to find, book, and cancel salon appointments via SalonRunner.

التثبيت

أضف هذا إلى إعدادات MCP في عميلك (Claude Desktop: claude_desktop_config.json، وCursor: ‏.cursor/mcp.json، ويستخدم VS Code وغيره الصيغة نفسها «mcpServers»).

NPM package salonrunner-mcp
Claude Code
claude mcp add salonrunner-mcp -e 'SALONRUNNER_SALON_ID=<SALONRUNNER_SALON_ID>' -e 'SALONRUNNER_USERNAME=<SALONRUNNER_USERNAME>' -e 'SALONRUNNER_PASSWORD=<your salonrunner_password>' -e 'SALONRUNNER_READ_ONLY=<SALONRUNNER_READ_ONLY>' -- npx -y salonrunner-mcp@0.2.0
إعداد JSON (Claude Desktop وCursor وVS Code)
{
    "mcpServers": {
        "salonrunner-mcp": {
            "command": "npx",
            "args": [
                "-y",
                "salonrunner-mcp@0.2.0"
            ],
            "env": {
                "SALONRUNNER_SALON_ID": "<SALONRUNNER_SALON_ID>",
                "SALONRUNNER_USERNAME": "<SALONRUNNER_USERNAME>",
                "SALONRUNNER_PASSWORD": "<your salonrunner_password>",
                "SALONRUNNER_READ_ONLY": "<SALONRUNNER_READ_ONLY>"
            }
        }
    }
}

متغيرات البيئة

  • SALONRUNNER_SALON_ID إلزامي Your salon's numeric id (from your booking URL)
  • SALONRUNNER_USERNAME إلزامي Your SalonRunner client login (same as the booking site)
  • SALONRUNNER_PASSWORD إلزامي سري Your SalonRunner client password
  • SALONRUNNER_READ_ONLY Set to 'true' to disable booking/cancelling (read-only)

التوثيق

مأخوذ من ملف README للمشروع على GitHub ويُحدَّث أسبوعيًا. تفتح الروابط على GitHub.

المحتويات
  1. salonrunner-mcp
  2. Tools
  3. How it works
  4. Configuration
  5. Option A — Local (Claude Desktop / Cursor / Copilot CLI)
  6. Option B — Remote (claude.ai custom connector)
  7. Security model
  8. Notes & limitations
  9. License

salonrunner-mcp

An MCP server that lets an AI assistant find, book, and cancel salon appointments through your personal SalonRunner / Rosy Salon Software client account — the same booking site many salons use.

It's self-hosted: you deploy your own instance. Run it locally as a tool (Claude Desktop, Cursor, Copilot CLI) where credentials stay on your machine, or as a remote connector for claude.ai where you log in with your SalonRunner account on the connector's login screen.

⚠️ Unofficial, uses undocumented endpoints, personal use only. Read DISCLAIMER.md.

Tools

ToolWhat it does
list_servicesList bookable services (name, id, price)
list_providersList stylists; optionally only those who do a given service
find_availabilityOpen slots for a service over a date range (optionally one provider)
list_my_appointmentsYour upcoming appointments
book_appointmentBook a slot returned by find_availability
cancel_appointmentCancel by appointment id

How it works

list/find/book/cancel
        │
   this server ──login──► app.salonrunner.com  (session cookie)
        │      ──authv2─► customer JWT (30 min, auto-refreshed)
        │      ──reads──► app.rosysalonsoftware.com/api/v2  (Bearer JWT)
        └──────writes───► /customer/appointments/{book,cancel}.json  (cookie)

customerId is discovered from your account after login; corporateId is read from the JWT. Availability is computed from the provider's per-service duration and the salon's slot grid (SALONRUNNER_SLOT_MINUTES, default 15).

Configuration

There are two ways to run it, and they get their salon credentials differently:

  • Local (stdio): credentials come from the environment (.env).
  • Remote (HTTP, claude.ai): credentials are entered on the connector's login screen and encrypted into the token — the server needs no salon credentials in its environment.
VariableUsed byNotes
SALONRUNNER_SALON_IDstdio (+ optional HTTP)The id in your booking URL …/customer/login.htm?id=XXXXX. In HTTP mode it's optional — if set, it pre-fills the salon id on the connector's login screen (handy for single-salon deployments and re-auth)
SALONRUNNER_USERNAME / SALONRUNNER_PASSWORDstdioYour client login
SALONRUNNER_CUSTOMER_IDbothAuto-discovered; set only if discovery fails
SALONRUNNER_SLOT_MINUTESbothSalon booking granularity (default 15)
SALONRUNNER_READ_ONLYbothtrue disables book/cancel while you try it out
SESSION_SIGNING_KEYHTTPSigns tokens + encrypts the credentials inside them; survives restarts/scale-to-zero (>=16 chars)
PUBLIC_URLHTTPThis server's public URL, e.g. https://your-app.fly.dev

In HTTP mode the salon id + username + password are collected on the login screen (validated by a real SalonRunner login) and encrypted into the OAuth token, so one deployment can serve multiple salons and there are no salon secrets on the server.

Option A — Local (Claude Desktop / Cursor / Copilot CLI)

Published on npm as salonrunner-mcp. Install globally:

npm install -g salonrunner-mcp

Then point your client at the salonrunner-mcp command (no build, no absolute paths). Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "salonrunner": {
      "command": "salonrunner-mcp",
      "env": {
        "SALONRUNNER_SALON_ID": "21248",
        "SALONRUNNER_USERNAME": "you@example.com",
        "SALONRUNNER_PASSWORD": "your-password"
      }
    }
  }
}

Prefer no global install? Use "command": "npx" with "args": ["-y", "salonrunner-mcp"] and the same env.

Run from a clone instead

npm install && npm run build

Then use "command": "node" with "args": ["/absolute/path/to/salonrunner-mcp/dist/stdio.js"] and the same env.

No hosting, no OAuth — credentials stay on your machine. Recommended if you don't need claude.ai.

Option B — Remote (claude.ai custom connector)

claude.ai can only use remote MCP servers, so you deploy your own instance.

Deploy to Fly.io
fly launch --no-deploy          # pick a unique app name; creates the app
fly secrets set \
  SESSION_SIGNING_KEY=$(node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))") \
  PUBLIC_URL=https://YOUR-APP.fly.dev
fly deploy
fly scale count 1               # in-memory MCP sessions: keep a single instance

No salon credentials are configured here — users supply them on the login screen. The server refuses to start without SESSION_SIGNING_KEY. Credentials are validated by a real SalonRunner login and then encrypted into the (signed) token, which claude.ai stores, so the app scales to zero between uses and you authorize only once — cold starts (~3s) are transparent and never re-prompt.

Connect in claude.ai
  1. Settings → Connectors → Add custom connector.
  2. URL: https://YOUR-APP.fly.dev/mcp
  3. Claude opens the connector's login screen → enter your salon id + username + password.
  4. The six tools appear in chat.
Run the remote server locally (testing)
SESSION_SIGNING_KEY=local-dev-please-change PUBLIC_URL=http://localhost:8787 npm run start:http

Security model

Two independent auth layers:

  1. claude.ai ↔ this server — OAuth 2.1 (PKCE + dynamic client registration). The login screen authenticates the user with a real SalonRunner login; the credentials are then AES-GCM encrypted and embedded inside the HMAC-signed token (keyed by SESSION_SIGNING_KEY). No server-side session store, so authorization survives restarts and scale-to-zero.
  2. this server ↔ SalonRunner — login → session cookie → short-lived JWT, auto-refreshed, using the credentials decrypted from the caller's token.

The server holds no salon credentials at rest — they live (encrypted) inside each user's token and are only decrypted in memory per request. One deployment can serve multiple salons. A leaked token can't be revoked individually; rotate SESSION_SIGNING_KEY to invalidate all tokens (everyone re-enters credentials once). Keep SESSION_SIGNING_KEY secret and serve only over HTTPS.

Notes & limitations

  • Built on undocumented customer endpoints; they can change without notice. Base URLs are configurable so you can adapt quickly.
  • Real bookings/cancellations incur the salon's cancellation-policy fees. Tools surface the service/provider/time before acting; consider running with SALONRUNNER_READ_ONLY=true first.
  • SALONRUNNER_SLOT_MINUTES must match your salon's scheduling grid (default 15) for accurate availability.
  • The officially documented, partner-only Rosy Salon Software API (api.salonrunner.com) is a separate product requiring a salon-issued ApiKey; this project does not use it.

License

MIT — see LICENSE. No warranty.

الأسئلة الشائعة

ما هو io.github.topness-msft/salonrunner-mcp؟

Self-hosted MCP to find, book, and cancel salon appointments via SalonRunner.

كيف أثبّت io.github.topness-msft/salonrunner-mcp؟

يعمل على جهازك. في Claude Code: claude mcp add salonrunner-mcp -e 'SALONRUNNER_SALON_ID=<SALONRUNNER_SALON_ID>' -e 'SALONRUNNER_USERNAME=<SALONRUNNER_USERNAME>' -e 'SALONRUNNER_PASSWORD=<your salonrunner_password>' -e 'SALONRUNNER_READ_ONLY=<SALONRUNNER_READ_ONLY>' -- npx -y salonrunner-mcp@0.2.0. وفي العملاء الآخرين، الصق إعداد JSON من هذه الصفحة في إعدادات MCP الخاصة بهم.

هل يحتاج io.github.topness-msft/salonrunner-mcp إلى مفتاح API؟

نعم. يتطلب SALONRUNNER_SALON_ID, SALONRUNNER_USERNAME, SALONRUNNER_PASSWORD، وتضبطها في إعداداته.

هل io.github.topness-msft/salonrunner-mcp مفتوح المصدر؟

نعم. شيفرته متاحة على GitHub بترخيص MIT.

من يصون io.github.topness-msft/salonrunner-mcp؟

ينشره topness-msft. يدرجه AI.tn لكنه لا يصونه ولا يوصي به.

من سجل MCP الرسمي. الإدراج ليس توصية: راجع شيفرة الخادم وصلاحياته قبل منحه الوصول إلى بياناتك.