@voltsbook/mcp
v0.1.0
Published
MCP server for the VoltsBook /v1 booking API — tools derived from the live OpenAPI contract.
Maintainers
Readme
@voltsbook/mcp
An MCP server for the VoltsBook appointment-booking API. It gives an AI agent — a desktop assistant, a voice receptionist, an automation — a set of tools for one business: read the catalogue, ask what is free, hold a slot, take a booking, move it, cancel it.
Tools are derived from the deployment's live /v1/openapi.json rather than hand-written,
so this package cannot drift from the API it talks to, and it works against any VoltsBook
deployment (hosted or self-hosted).
Zero runtime dependencies.
Two doors
You do not need this package to use VoltsBook over MCP. There are two ways in, and they
serve the same tools because both derive them from the same contract and both execute
through the same /v1 HTTP surface.
1. Hosted — POST https://app.voltsbook.com/mcp
Nothing to install. Point an MCP client at the URL with your API key as a bearer token:
{
"mcpServers": {
"voltsbook": {
"type": "http",
"url": "https://app.voltsbook.com/mcp",
"headers": { "Authorization": "Bearer vb_live_your_key" }
}
}
}Stateless Streamable HTTP: every request creates nothing and remembers nothing, so a dropped connection costs a retry rather than a wedged stream.
Prefer this door for scoped keys. It authenticates before listing, so tools/list
returns only the tools the presented key can actually call.
2. Local — npx -y @voltsbook/mcp
For clients that only speak stdio, or when you want the traffic to leave your own machine:
{
"mcpServers": {
"voltsbook": {
"command": "npx",
"args": ["-y", "@voltsbook/mcp"],
"env": { "VOLTSBOOK_API_KEY": "vb_live_your_key" }
}
}
}Transport is the MCP stdio spec: newline-delimited JSON-RPC 2.0 on stdin/stdout, with all logging on stderr (a stray stdout line would corrupt the stream).
Configuration
| Variable | Required | Default | What it does |
|---|---|---|---|
| VOLTSBOOK_API_KEY | yes | — | The /v1 API key. Create one in the VoltsBook panel under Settings → API keys. Missing, the process exits 1 with that sentence on stderr. |
| VOLTSBOOK_API_URL | no | https://app.voltsbook.com | The deployment to talk to. Set it for a self-hosted install. A trailing slash is trimmed. |
There are no command-line arguments — an MCP client launches the binary and speaks the protocol; anything configurable is an environment variable, because that is what every MCP client config can set.
The contract is fetched once at startup. If <VOLTSBOOK_API_URL>/v1/openapi.json cannot
be read, the process exits 1 rather than serving a stale or empty tool list.
Scopes — what a key can see
A VoltsBook API key carries scopes, and the tool list follows them. As of the current contract there are 46 tools:
| Scope | Tools | What it covers |
|---|---|---|
| booking | 15 | The catalogue, availability, reservations, and creating/moving/cancelling bookings. This is what every key held before scopes existed. |
| catalog.manage | 9 | Create, edit and delete services, their extras, and products. |
| settings.manage | 21 | Booking rules and settings, booking forms, appointment statuses, offers, and guided flows. |
| reports.read | 1 | Appointment and revenue figures. |
So a booking-scoped key — the right one for a customer-facing voice agent — sees 15 tools, and a key holding every scope sees all 46.
The two doors differ in when that filter is applied:
- Hosted
POST /mcpauthenticates first, sotools/listis filtered to the key's scopes. A booking-only agent is never offereddeleteService, and never spends context window on schemas it cannot call. - stdio (
npx) fetches the contract unauthenticated, so the key's scopes are unknown to it and the full list is served. Calling a tool the key does not cover is refused by the server withinsufficient_scope, naming the scope it needed and the scopes the key holds.
Filtering is curation, not the security boundary. Every call is authorised server-side
by the same guard that protects /v1 directly, whichever door it came through.
The booking flow
listServices → getAvailability → createBooking…optionally with createReservation between the last two to hold the slot while the human
decides. Every instant is UTC; money is integer minor units (2500 is £25.00).
Slots are not reserved by being read: a booking can still be refused with slot_taken if
somebody else got there first. Ask for availability again rather than retrying the same
slot.
Protocol
JSON-RPC 2.0, MCP protocol version 2025-06-18 (2024-11-05 and 2025-03-26 are accepted
and echoed). Implemented methods: initialize, tools/list, tools/call, ping.
Capabilities beyond tools are declined honestly at initialize.
Links
- Agent + voice-agent guide: https://voltsbook.com/developers/agents
- API reference: https://voltsbook.com/developers
Licence
MIT
