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
- 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/mbayucot/booking-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server