npm salonrunner-mcpstdioMITupdated 2mo ago
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.
What can you do with salonrunner mcp?
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
| Tool | What it does |
|---|---|
list_services |
List bookable services (name, id, price) |
list_providers |
List stylists; optionally only those who do a given service |
find_availability |
Open slots for a service over a date range (optionally one provider) |
list_my_appointments |
Your upcoming appointments |
book_appointment |
Book a slot returned by find_availability |
cancel_appointment |
Cancel 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.
| Variable | Used by | Notes |
|---|---|---|
SALONRUNNER_SALON_ID |
stdio (+ 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_PASSWORD |
stdio | Your client login |
SALONRUNNER_CUSTOMER_ID |
both | Auto-discovered; set only if discovery fails |
SALONRUNNER_SLOT_MINUTES |
both | Salon booking granularity (default 15) |
SALONRUNNER_READ_ONLY |
both | true disables book/cancel while you try it out |
SESSION_SIGNING_KEY |
HTTP | Signs tokens + encrypts the credentials inside them; survives restarts/scale-to-zero (>=16 chars) |
PUBLIC_URL |
HTTP | This 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.
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
- Settings β Connectors β Add custom connector.
- URL:
https://YOUR-APP.fly.dev/mcp - Claude opens the connector's login screen β enter your salon id + username + password.
- 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:
- 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. - 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=truefirst. SALONRUNNER_SLOT_MINUTESmust 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.
Install
Add salonrunner mcp to your client. Pick the one you use.
claude mcp add salonrunner-mcp -- npx -y salonrunner-mcpcodex mcp add salonrunner-mcp -- npx -y salonrunner-mcpamp mcp add salonrunner-mcp -- npx -y salonrunner-mcp{
"mcpServers": {
"salonrunner-mcp": {
"command": "npx",
"args": [
"-y",
"salonrunner-mcp"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"salonrunner-mcp": {
"command": "npx",
"args": [
"-y",
"salonrunner-mcp"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
code --add-mcp '{"name":"salonrunner-mcp","command":"npx","args":["-y","salonrunner-mcp"]}'Or add the block manually to `.vscode/mcp.json` under `servers`.
{
"mcpServers": {
"salonrunner-mcp": {
"command": "npx",
"args": [
"-y",
"salonrunner-mcp"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"salonrunner-mcp": {
"command": "npx",
"args": [
"-y",
"salonrunner-mcp"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"salonrunner-mcp": {
"command": "npx",
"args": [
"-y",
"salonrunner-mcp"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"salonrunner-mcp": {
"type": "local",
"command": "npx",
"args": [
"-y",
"salonrunner-mcp"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"salonrunner-mcp": {
"command": {
"path": "npx",
"args": [
"-y",
"salonrunner-mcp"
]
}
}
}
}Add to your Zed `settings.json`.
npx -y salonrunner-mcpRun `goose configure`, choose **Add Extension β Command-line Extension**, and paste this command.
6 tools
salonrunner mcp exposes 6 tools to a connected agent.
- list_services
- List bookable services (name, id, price)
- list_providers
- List stylists; optionally only those who do a given service
- find_availability
- Open slots for a service over a date range (optionally one provider)
- list_my_appointments
- Your upcoming appointments
- book_appointment
- Book a slot returned by `find_availability`
- cancel_appointment
- Cancel by appointment id
Score
72 / 100
Good
- Documentation25/25
- Maintenance16/25
- Trust13/20
- Capability6/15
- Install experience12/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 56 days ago
- Has a release history
- Repository is not archived
- Licensed MIT
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 6 tool(s) documented
- Provides prompt templates
- Provides resources
- 12 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint β no local install
Version history
| Versions | Published |
|---|---|
| 0.2.0Latest | Jul 7, 2026 |
| 0.1.0 | Jul 1, 2026 |