booking-mcp
Integrates with a PostgreSQL database to manage booking data, providing tools for staff management, appointment scheduling, client records, and availability search.
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., "@booking-mcpbook a cleaning for next Tuesday morning"
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.
booking-mcp
A standalone MCP server (built on
FastMCP) that exposes the booking datastore — the same
PostgreSQL database the booking-agent app uses — to any
MCP-compatible client. It is decoupled: it does not import booking-agent, but
connects to the shared DB with its own SQLAlchemy layer. booking-agent owns the
schema and migrations; a schema-contract test guards against drift.
Features
Resources (read-only, URI-addressed)
URI | Returns |
| active cleaners (skills + location) |
| one staff member |
| appointments on a date |
| client + contacts + saved preferences |
Tools — read (readOnly, idempotent)
search_availability(service, date, time, latitude?, longitude?, radius_km?)— staff who can do the job, are free at the slot, and within range (the same skill/free/geo filter the booking engine uses).find_next_available(service, date, time, days?, …)— first day within the window with a free, qualified cleaner.list_staff(skill?),daily_schedule(date),get_client(email).
Tools — write (only when READ_ONLY=false; each asks for confirmation via MCP elicitation before writing)
create_booking(...)— client + job + appointment, idempotent (deduped on a hash of all material fields).cancel_booking(appointment_id)— idempotent delete.reschedule_booking(appointment_id, date, time)— moves a slot (rejects staff conflicts).add_customer_preference(email, note).book_from_text(request)— parses a free-text request using the client's LLM via MCP sampling, then confirms and books. Requires a sampling-capable client. Idempotent.
Writes go directly to the DB and bypass booking-agent's approval workflow. Use the workflow bridge below if you want human approval.
Tools — workflow bridge (only when BOOKING_AGENT_URL is set; routes through booking-agent's human-approval workflow over HTTP)
book_via_workflow(message)— start an approval run from a natural-language request →{run_id, status}.get_workflow_run(run_id)— poll status and the final response.decide_workflow_run(run_id, approve, by?, reason?)— submit the approve/reject decision.
Prompts: book_cleaning(...), summarize_schedule(date).
All inputs are validated (real calendar dates/times, email format); all outputs are typed (structured content).
Related MCP server: PostgreSQL MCP Server
Quickstart
cp .env.example .env # point DATABASE_URL at the shared Postgres
make install # uv sync --dev
make dev-up # start Postgres on :5433 (Docker)
make seed # create_all + demo data (requires STANDALONE_MODE guard)
make server # run in stdio modeFor the HTTP transport on the host: make server-http (binds :8000).
Fully standalone (own DB + data) — no booking-agent needed. One-shot the whole stack:
make stack-up # docker compose up (db + seed + mcp on :8000)booking-mcp-seed bootstraps the schema with create_all and populates demo staff, clients,
appointments, and preferences so the read tools return data immediately. STANDALONE_MODE=true
is required — the guard prevents accidental schema mutation against a shared DB. When sharing a
DB with booking-agent, skip the seed: booking-agent owns the canonical Alembic migrations.
API / Usage
Any MCP client takes the standard mcpServers config (the same JSON an mcp add accepts).
Local (stdio) — the client launches the server as a subprocess; local and trusted, so no auth:
{
"mcpServers": {
"booking": {
"command": "/ABS/PATH/booking-mcp/.venv/bin/booking-mcp",
"env": {
"DATABASE_URL": "postgresql+psycopg://booking:booking@localhost:5432/booking",
"READ_ONLY": "true"
}
}
}
}(booking-mcp is the console script installed into the venv.)
Remote (HTTP) — connect over the streamable-HTTP transport with a Bearer key. Mint a key, then
pass the hash in API_KEYS (the server refuses to start write-enabled over HTTP without credentials):
# 1. Mint a key (prints plaintext once + the JSON record to add to API_KEYS)
# Available scopes: read, write, workflow, pii (grant only what the client needs)
booking-mcp-mintkey --client claude-desktop --scopes read,write,pii
# 2. Start the server
API_KEYS='[{"hash":"<paste-hash>","client_id":"claude-desktop","scopes":["read","write","pii"]}]' \
READ_ONLY=false booking-mcp{
"mcpServers": {
"booking": {
"url": "http://your-host:8000/mcp",
"headers": { "Authorization": "Bearer <plaintext-key>" }
}
}
}A client with no/wrong key gets 401. Scope enforcement is strict: a key without read cannot
see read tools; write/workflow/pii are additional gates on top. stdio needs no token
(local/trusted — all surfaces are open).
Legacy:
AUTH_TOKEN=<token>still works as a single full-access fallback but is deprecated — it grants read+write with no scope isolation. Migrate toAPI_KEYS.
Development
Common make targets:
Target | What it runs |
|
|
| Postgres container lifecycle |
| Schema + demo data ( |
| stdio server on host |
| HTTP server on host ( |
| Full containerised stack |
| Mint an API key |
| psql shell into the running container |
|
|
|
|
|
|
|
|
|
|
Testing
make test # pytest --cov=booking_mcp — requires 100% coverage to passIn-memory client: tools/resources are exercised through
fastmcp.Clientagainst the server object — no subprocess.Testcontainer Postgres: the MCP's own
create_allschema, truncated per test (real FK/types).Schema-contract test (
test_schema_contract.py): when../booking-agent/backendis checked out, it applies booking-agent's real Alembic migrations to a fresh container and runs the MCP queries against them — catching any drift between this server's models and the owning service's schema. Skips when booking-agent isn't present.
Configuration
Copy .env.example to .env. All settings are read from the environment (or .env).
Variable | Default | Purpose |
|
| The same Postgres booking-agent uses; booking-agent owns the schema, this is a client. |
|
| Set to |
|
| Must be |
| (empty) | Preferred HTTP auth. JSON array of |
| (empty) | Deprecated: single static token granting full access (all scopes). Superseded by |
|
| Mask phone numbers (last-4 digits) and addresses ( |
|
| Redirect |
| (empty) | When set, the workflow-bridge tools are registered and POST to booking-agent so a booking goes through its full approval workflow. Decoupled: HTTP only, no import. |
|
| HTTP timeout (seconds) for workflow-bridge calls to booking-agent. |
|
| Cap on the client's LLM sampling call in |
|
| Connection pool size (sized for FastMCP's sync-tool threadpool). |
|
| Pool overflow beyond |
|
| Recycle connections after this many seconds. |
|
| Seconds to wait for a pooled connection. |
|
| Per-query statement timeout (ms). |
|
| Logging level. |
Notes
Schema ownership: in standalone mode (
STANDALONE_MODE=true),booking-mcp-seedbootstraps the schema withcreate_all. When sharing a DB with booking-agent, booking-agent owns the canonical Alembic migrations — skip the seed entirely, and the schema-contract test guards against model drift.No FastAPI/LangGraph — FastMCP brings its own (Starlette/uvicorn) HTTP stack for the HTTP transport.
MCP client features used: elicitation (write confirmation), sampling (
book_from_text). Both degrade gracefully — a client that doesn't support them just can't call those tools.Per-resource content subscriptions and argument completions are not supported — neither is first-class in this FastMCP version. Clients re-read
booking://schedule/{date}for fresh data.
License
MIT — see LICENSE.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
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/mbayucot-dev/booking-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server