acuity-mcp
acuity-mcp
A local MCP server exposing the Acuity Scheduling API as Claude Code tools — list/create/reschedule/cancel appointments, check availability, list appointment types, calendars, and clients, all directly from a Claude session. Supports multiple Acuity accounts side by side, switchable per tool call.
Built custom because no maintained free MCP for Acuity exists — the only GitHub repo found during
research pointed at an npm package that was never published. Uses @modelcontextprotocol/sdk +
zod, runs over stdio.
If you're Claude: read this first
If a user asks you to set this up, add an Acuity account, switch accounts, or troubleshoot a
connection, load .claude/skills/acuity-mcp-setup/SKILL.md in this repo — it has the full
step-by-step for all of that. This README is the human-facing reference; the skill is what you
should actually follow.
What you need before setup
An Acuity Scheduling User ID and API Key, from Acuity: Business Settings → Integrations → API. One pair per Acuity account you want to connect.
⚠️ Acuity gates API access by plan tier. Some plans return 403: API access is only available on Powerhouse plans for every request — this is Acuity rejecting your account, not a bug here.
Basic Auth succeeding (no 401) but every call still 403-ing is the signature of this. If you
hit it, either upgrade the plan, or use an alternative path to the same account (e.g. a Zapier
Acuity connector, which has empirically not been subject to the same restriction).
Install
npm installQuick start — one account
node bin/acuity-accounts.js add production --user-id <your-user-id> --api-key <your-api-key>The first account you add automatically becomes the default. Then register the server with Claude Code:
claude mcp add acuity -s user -- node "$(pwd)/server.js"Start a new Claude Code session (or run /mcp in an existing one) so the tools show up.
Verify it works without a Claude session at all:
node bin/acuity-accounts.js testMultiple accounts
Add as many named accounts as you want:
node bin/acuity-accounts.js add production --user-id 1111111 --api-key aaaa... --label "Real account"
node bin/acuity-accounts.js add sandbox --user-id 2222222 --api-key bbbb... --label "Trial/test account"Credentials live in ~/.config/acuity-mcp/accounts.json (chmod 600, never inside this repo,
never committed). Manage them:
node bin/acuity-accounts.js list # see configured accounts (never prints API keys)
node bin/acuity-accounts.js set-default sandbox # change which one is used by default
node bin/acuity-accounts.js remove sandbox # remove one
node bin/acuity-accounts.js test sandbox # verify one specific account's credentialsSwitching accounts inside a Claude session doesn't require re-registering anything — every
tool this server exposes accepts an optional account argument:
"List appointment types for the sandbox account" → Claude calls
list_appointment_typeswith{"account": "sandbox"}.
Ask Claude to run list_accounts at any time to see what's configured and which is default.
If you'd rather run fully separate MCP server registrations per account instead (e.g. so each
shows up as a distinctly-named server), that still works — point ACUITY_ACCOUNT at a name
instead of passing account per call:
claude mcp add acuity-production -s user -e ACUITY_ACCOUNT=production -- node "$(pwd)/server.js"
claude mcp add acuity-sandbox -s user -e ACUITY_ACCOUNT=sandbox -- node "$(pwd)/server.js"Credential resolution order
ACUITY_USER_ID+ACUITY_API_KEYenv vars (direct override, no accounts file needed)accountargument on a tool call, or theACUITY_ACCOUNTenv var — looked up by nameaccounts.json's owndefaultaccountaccounts.jsonwith exactly one account configured — used automaticallyLegacy flat
~/.config/acuity-mcp/credentialsfile (ACUITY_USER_ID=.../ACUITY_API_KEY=...lines) — supported for backward compatibility with older single-account setups
Tools
Local only, no Acuity API call:
list_accounts— list configured account names/labels and the default (never API keys)
Read-only:
list_appointment_types— list bookable consult typeslist_calendars— list calendars/stafflist_appointments— filterable by date range / calendar / type / canceled statusget_appointment— full detail on one appointment by IDcheck_availability_dates— available dates in a month for an appointment typecheck_availability_times— available time slots on a date for an appointment typelist_clients— clients who have booked appointments
Mutating (real changes to the live calendar — Claude will ask for confirmation before calling these):
create_appointment— book a new appointmentreschedule_appointment— change an appointment's date/timecancel_appointment— cancel an appointment
All tools accept an optional account argument (see Multiple accounts).
Not implemented (same pattern, add later if needed): payments, blocks, forms, webhooks, gift certificates.
Lessons learned (read before extending this server)
A
200 OKfrom a mutating call does not prove the mutation happened.reschedule_appointmentoriginally calledPUT /appointments/:id, which returned200and echoed back the unchanged appointment — Acuity silently ignored thedatetimefield on that endpoint. The fix was the dedicatedPUT /appointments/:id/rescheduleroute, matching the patterncancel_appointmentalready used (/appointments/:id/cancel). Always re-fetch withget_appointmentafter a write before trusting it, especially for any new mutating tool added later.npx @modelcontextprotocol/inspector --clidoes not reliably forward ad-hoc env vars to thenode server.jsprocess it spawns. If you're testing credentials that aren't already the resolved default (e.g.ACUITY_USER_ID=x ACUITY_API_KEY=y npx @modelcontextprotocol/inspector --cli ...), it can silently fall back to whatever's already configured and give a false positive/negative. Usenode bin/acuity-accounts.js test <name>instead — built specifically to avoid this trap. The inspector CLI remains fine for its original purpose: testing the resolved default credentials, or--method tools/listto check tool schemas.
Manual verification
node bin/acuity-accounts.js test # tests the default/env-resolved account
node bin/acuity-accounts.js test <name> # tests one specific named account
npx @modelcontextprotocol/inspector --cli node server.js --method tools/list # confirms the server starts and tools register correctlyLatest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/walakaka77/acuity-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server