appointment-scheduler-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@appointment-scheduler-mcpCan you book a haircut for me on Monday at 2pm?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Appointment Scheduler API
A small REST API for booking, rescheduling, and cancelling appointments, built with Node.js, Express, and TypeScript. Data is kept in an in-memory store, so it's meant for local development, demos, and testing rather than production use.
Full CRUD for appointments, users, and services, plus provider availability lookups — matching the accompanying OpenAPI spec.
Component diagram
flowchart LR
Client([HTTP Client])
subgraph API["Express App (src/app.ts)"]
AuthMW["Auth middleware\nBearer token check"]
Routes["Routes\nappointments / users /\navailability / services"]
Controllers["Controllers\nvalidation +\nbusiness rules"]
Store[("In-memory data store\n(data/store.ts)")]
ErrorMW["Error middleware\nApiError -> 400/401/404/409,\nelse 500"]
end
Client -- "HTTP request" --> AuthMW
AuthMW --> Routes
AuthMW -. "throws ApiError (401)" .-> ErrorMW
Routes --> Controllers
Controllers -- "read / write" --> Store
Store -. "data" .-> Controllers
Controllers -. "throws ApiError" .-> ErrorMW
Controllers -- "JSON response" --> Client
ErrorMW -- "JSON response" --> ClientGET /health bypasses the auth middleware entirely (not pictured above, for simplicity) — deploy platforms and load balancers need to reach it without a token. Rate limiting (see below) sits between the health route and the auth middleware, so it also isn't pictured — a 429 from it never reaches ErrorMW, since express-rate-limit sends its own JSON response directly.
Related MCP server: MCP Appointment Booking Server
Requirements
Node.js 18+ (developed/tested on Node 22)
npm
Install
npm installEnvironment variables
Copy the example file and adjust as needed:
cp dev.env.example dev.envVariable | Description | Default |
| Port the HTTP server binds to |
|
| Bearer token required in the |
|
| Only used by the MCP server to reach the running API |
|
dev.env is loaded automatically on startup (via dotenv) and is git-ignored, so local overrides never get committed. dev.env.example is the committed template — keep it in sync whenever a new variable is added.
Run
# Development (auto-reload on file changes)
npm run dev
# Production
npm run build
npm startThe server listens on http://localhost:8080 by default. Override the port by setting PORT in dev.env (or as an environment variable directly). Every request is logged to stdout (method, path, status, response time) via morgan.
Authentication
Every endpoint requires a bearer token matching API_TOKEN, sent in the Authorization header:
curl http://localhost:8080/services \
-H "Authorization: Bearer $API_TOKEN"Missing, malformed, or incorrect tokens get a 401 response. This is a single shared static token (no per-user login, sessions, or expiry) — enough to demonstrate an auth-protected API without adding a user/identity system to a project meant to stay small.
Rate limiting
Every endpoint except /health is rate-limited per IP. Callers can optionally send X-Client-Type: human, agent, or service to self-identify — doing so raises the limit from 60 to 150 requests/minute (any other or missing value is treated as unidentified). This isn't an auth mechanism (the value is self-declared, not verified); it's a fair-use signal, and it's also echoed into the server logs ([client=agent]) and the business-rule log lines in the controllers, so agent traffic is visible and distinguishable from human traffic without any extra tracing. Exceeding the limit returns 429.
curl http://localhost:8080/services \
-H "Authorization: Bearer $API_TOKEN" \
-H "X-Client-Type: agent"Booking rules
POST /appointments and PUT /appointments/:id reject a date that's before today or more than a year out (400). Combined with the fixed weekly schedule in PROVIDER_BASE_SLOTS, this keeps bookings within a sensible window without needing a real calendar/scheduling system behind it. The full set of validation rules (unknown user/provider/service, time slots the provider doesn't offer, etc.) is documented in the OpenAPI spec.
MCP server
src/mcp/server.ts exposes this API to AI agents as an MCP server over stdio — list_users, list_services, check_availability, book_appointment, list_appointments, and cancel_appointment. It's a normal authenticated HTTP client of the real running API (it calls /appointments, /users, etc. over fetch, sending Authorization: Bearer $API_TOKEN and X-Client-Type: agent) — it doesn't import controllers or touch the in-memory store directly, so everything in the Rate limiting and Booking rules sections above applies to it exactly as it would to any other caller.
Two deliberate restrictions, both enforced in the MCP tool layer rather than the REST API: there's no create_user tool (the REST API supports creating users; agents can't autonomously add identity records through MCP), and list_users only returns id/name — never email/phone — since that's all book_appointment's name matching actually needs. GET /users itself is unaffected by either restriction; a normal authorized caller still gets full user records.
Run the API first, then the MCP server in a separate terminal:
npm run dev # terminal 1 — the real API, must be running
npm run mcp # terminal 2 — the MCP server (stdio)To try it interactively without wiring up an agent, use the MCP Inspector:
npx @modelcontextprotocol/inspector npx tsx src/mcp/server.tsTest
# Run the test suite once
npm test
# Watch mode
npm run test:watch
# Type-check only
npm run lintTests use Vitest and Supertest to exercise the Express app directly (no running server required), covering the main CRUD flows and the 400/401/404/409 error paths for each resource, plus a dedicated rate-limiter unit test (src/middleware/rateLimiter.test.ts) and a contract-test suite (src/test/contract/) that validates real responses against docs/openapi.yaml's schemas, so the spec can't silently drift from what the API actually returns. A GitHub Actions workflow (.github/workflows/ci.yml) runs npm run lint and npm test on every push and pull request.
Project structure
src/
types/ Shared TypeScript interfaces
data/store.ts In-memory seed data and id counters
utils/ ApiError, and client-type detection for logs/rate limiting
controllers/ Request handling + validation per resource
routes/ Express routers, one per resource
middleware/ Auth, rate limiting, 404, and centralized error handling
mcp/ MCP server exposing the API as agent-callable tools
test/contract/ Validates real responses against docs/openapi.yaml
app.ts Express app factory
index.ts Server entrypointAPI docs
OpenAPI spec:
docs/openapi.yamldescribes every endpoint, request/response schema, and error case. Paste it into editor.swagger.io or any OpenAPI viewer to browse it interactively.
API overview
Method | Path | Description |
GET | /health | Health check (no auth required) |
GET | /appointments | List all appointments |
POST | /appointments | Book a new appointment |
GET | /appointments/:id | Get a specific appointment |
PUT | /appointments/:id | Reschedule an appointment |
DELETE | /appointments/:id | Cancel an appointment |
GET | /users | List all users |
POST | /users | Create a new user |
GET | /users/:id | Get a specific user |
PUT | /users/:id | Update a user |
DELETE | /users/:id | Delete a user (409 if they have appointments) |
GET | /availability | List provider availability |
GET | /services | List all services |
POST | /services | Create a new service |
GET | /services/:id | Get a specific service |
PUT | /services/:id | Update a service |
DELETE | /services/:id | Delete a service (409 if it has appointments) |
Full request/response shapes are defined in the OpenAPI spec provided with this project.
License
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityDmaintenanceAn MCP server that enables interaction with OnSched's consumer-facing appointment scheduling API through natural language, allowing users to manage bookings, appointments, and scheduling operations.Last updated
- Alicense-qualityDmaintenanceAn MCP server that enables users to book, cancel, reschedule, and list appointments through natural language interactions. It uses YAML configurations for agent behavior and function logic to manage appointment data and availability.Last updatedMIT
- AlicenseAqualityBmaintenanceAgent-native MCP server for Carly, the AI scheduling assistant. Exposes 11 tools to read and manage booking pages, event types, calendars, bookings, and available slots. Allows you to manage and create booking pages from the command line.Last updated13173MIT
- Alicense-qualityCmaintenanceMCP server that connects AI agents to calendars, bookings, and scheduling polls via the Model Context Protocol.Last updated33MIT
Related MCP Connectors
Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.
MCP server exposing the Backtest360 engine API as tools for AI agents.
Hosted MCP server exposing US hospital procedure cost data to AI assistants
Latest 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/ProductDock/appointment-scheduler-api'
If you have feedback or need assistance with the MCP directory API, please join our Discord server