OpenBook
Allows syncing appointments and availability with Google Calendar.
Click on "Deploy 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., "@OpenBookBook a fade with Marcus at Fade Studio Saturday afternoon."
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.
OpenBook
Open-source appointment booking for small businesses (barbershops, salons, studios), built for voice. Customers book, reschedule and cancel by talking to Alexa+ or any other MCP client; the assistant talks to OpenBook through a Model Context Protocol server.
🧑 "Book a fade with Marcus at Fade Studio Saturday afternoon." 🔊 "Marcus has three times available Saturday afternoon: 12:30 PM, 1:15 PM, or 3 PM. Which one works for you?"
(a real reply from the simulated Alexa+: Claude on Amazon Bedrock calling
list_servicesandsearch_availabilityon the OpenBook MCP server)
Built for the Amazon Developer Hackathon (Alexa+ track, AWS Builder and Open Source challenges).
Status
OpenBook is being built in milestones. This section is kept honest: only what is listed as done exists and is tested.
# | Milestone | Status |
1 | Foundation: monorepo, Postgres schema with exclusion constraints, seed data, CI | ✅ Done |
2 | Core domain: availability, holds, bookings, reschedule, cancel, idempotency | ✅ Done |
3 | MCP server (Streamable HTTP, 8 tools, dev auth) | ✅ Done |
4 | Simulated Alexa+ ( | ✅ Done |
5 | Owner dashboard | ✅ Done |
6 | Notifications + outbox worker | ✅ Done |
7 | Cognito OAuth + AWS CDK deployment + connect to real Alexa+ (MCP Toolkit) | ✅ Deployed² |
8 | Stretch: Bedrock Knowledge Base FAQ, Google Calendar | ✅ Built¹ |
9 | Polish: README, architecture, demo script, friction log, product feedback | ✅ Done |
10 | Store finder: live "salons near me" search (OpenBook + real-world shops) | ✅ Done |
¹ Code and tests done; the Knowledge Base is created on AWS deploy, and Google Calendar needs a Google OAuth client, so neither has been exercised against the live service yet.
² Deployed to AWS (us-east-1) on 2026-09-24: API health, the MCP OAuth 401 challenge and metadata, migrations + seed, and the web app verified live. The Alexa+ registration still needs the project owner's Alexa developer account.
Architecture: docs/ARCHITECTURE.md. Every design decision: docs/DECISIONS.md.
What works today:
End to end by voice:
docker compose up, openhttp://localhost:3000/assistant, hold the button and talk. The simulated Alexa+ (Claude Haiku 4.5 on Amazon Bedrock, Converse API with tool use) books, reschedules and cancels through the OpenBook MCP server, answers questions from the business's policies, and shows every MCP tool call with its arguments and result. Verified live: book → parking question → reschedule → list → cancel with the $10 late fee quoted first.Owner dashboard at
http://localhost:3000/dashboard(local "Dev login" as Fade Studio's owner): day/week calendar by staff member with cancel and no-show, services, staff with services and weekly hours, time off, policies and FAQ, settings with the MCP endpoint URL and a copy button. Backed by an owner REST API (/api/v1, same server as MCP) that authorises every request againstbusiness_owners. Changes reach the voice assistant immediately. A Playwright test covers "owner creates a service → it appears inlist_services".Store finder (live): choose "Any shop near me" on
/assistantand ask "find me a barber near Williamsburg that can do a shave today". OpenBook shops come back with distance, open now and the next free slot (bookable right there), plus real-world shops from Amazon Location Service (name, distance, hours, phone; not bookable). Served by the directory MCP endpoint/mcp.Notifications: every booking, reschedule and cancellation queues a message in the outbox; the worker sends a confirmation SMS and email (Amazon SES / AWS End User Messaging in AWS, logged locally), retrying with backoff and never sending a channel twice.
docker compose upstarts Postgres 16, applies migrations, seeds two demo businesses, and runs the MCP server (:3001) and web app (:3000).The database itself rejects double bookings, overlapping holds, bookings inside another appointment's buffer, and cross-tenant references (see Data integrity).
MCP server at
http://localhost:3001/mcp/{businessSlug}: Streamable HTTP, stateless, JSON responses, built on the official MCP TypeScript SDK v2. It serves MCP 2026-07-28 and the 2025-era protocol (including 2025-11-25). All 8 tools are listed in docs/MCP_TOOLS.md. Tools return speakable text plus structured data, and stable error codes.OAuth 2.1 resource-server behaviour:
401+ RFC 9728 challenge, JWT validation against a JWKS (issuer, expiry, audience/client id), per-business protected-resource metadata. Locally,DEV_AUTHsigns in as the demo customer Jen. Real Cognito sign-in is milestone 7.Verified with MCP Inspector 2.8.0 (tools/list, tools/call) against the Docker Compose stack.
packages/coreholds every booking rule: availability (working hours, buffers, time off, notice, horizon, DST-safe), 5-minute holds, booking, rescheduling, cancellation with the late fee, idempotent writes, a transactional outbox, service/staff matching for spoken requests, and policy-based FAQ answers.165 tests, including 20 concurrent holds for one slot (exactly one wins), concurrent retries with one idempotency key (one booking), tenant isolation, a full book → reschedule → cancel flow driven by the SDK client over Streamable HTTP in both protocol eras, and the Bedrock ↔ MCP agent bridge against the real server (with a scripted model, so CI needs no AWS account).
Not yet: notifications are queued in the outbox but not sent (milestone 6), the owner dashboard (milestone 5), and AWS deployment with Cognito sign-in (milestone 7). The assistant signs in as the demo customer Jen with the development token.
Related MCP server: MCP Medical Appointments Demo
Quick start
Requirements: Docker. For the voice assistant, AWS credentials with Amazon Bedrock access to a
Claude model (your ~/.aws profile is mounted read-only, or export AWS_PROFILE /
AWS_ACCESS_KEY_ID etc.). For development also Node.js 24 and pnpm 10.
docker compose upThen open http://localhost:3000/assistant (Chrome or Edge for speech recognition; any browser works with the text box), hold the button and say "Book a fade with Marcus Saturday afternoon."
This starts Postgres on localhost:54329, runs migrations, seeds demo data (only the first time;
your bookings survive restarts), and starts the MCP server on localhost:3001 and the web app on
localhost:3000. The default model is us.anthropic.claude-haiku-4-5-20251001-v1:0 in
us-east-1; set BEDROCK_MODEL_ID / AWS_REGION to change it. Without Bedrock access the page
still loads and says why it can't answer.
The MCP server works on its own too:
curl localhost:3001/healthz
npx @modelcontextprotocol/inspector --cli http://localhost:3001/mcp/fade-studio --transport http \
--header "Authorization: Bearer dev-token-jen-0123456789" --method tools/listTo wipe and reseed:
SEED_RESET=true docker compose upDemo data
Business | Slug | Time zone | Staff | Services |
Fade Studio |
| America/New_York | Marcus, Dana | Fade (45 min, $35), Beard Trim (20 min, $15), Cut & Beard (60 min + 5 min buffer, $45) |
Glow Salon |
| America/Los_Angeles | Priya | Blowout (45 min, $40), Haircut (60 min + 10 min buffer, $65) |
Fade Studio is open Tuesday–Saturday, 9 AM–6 PM, has a 24-hour cancellation window with a $10
late fee, welcomes walk-ins, and has free street parking on Elm St. The upcoming Saturday is
partly booked so availability looks realistic. Demo customer Jen (OAuth subject dev|jen)
exists in both businesses as separate customer records.
Architecture
flowchart LR
subgraph Browser
A["/assistant<br/>push-to-talk (Web Speech API)<br/>speech synthesis · Tool calls panel"]
end
subgraph web["apps/web (Next.js)"]
R["POST /api/assistant<br/>agent loop"]
end
subgraph AWS
B["Amazon Bedrock<br/>Claude · Converse API + tool use"]
end
subgraph mcp["apps/mcp-server (Hono + MCP SDK v2)"]
M["POST /mcp/{businessSlug}<br/>Streamable HTTP · stateless · JSON<br/>OAuth 2.1 resource server"]
T["8 tools<br/>get_business_info · list_services · search_availability · hold_slot<br/>create_booking · find_my_bookings · reschedule_booking · cancel_booking"]
end
C["packages/core<br/>availability · holds · bookings<br/>idempotency · policies"]
D[("PostgreSQL 16<br/>exclusion constraints<br/>outbox")]
X["Any MCP client<br/>(Alexa+, MCP Inspector, desktop assistants)"]
A -- "what the customer said" --> R
R -- "Converse (messages + tool specs)" --> B
B -- "toolUse" --> R
R -- "MCP tools/list, tools/call<br/>Bearer token" --> M
X -- "MCP over Streamable HTTP" --> M
M --> T --> C --> DEach spoken turn: the page sends the transcript to /api/assistant, which asks Bedrock what to
do. The model's tool calls go to the MCP server exactly as any MCP client's would, and the reply
is spoken back. The panel under each reply lists those MCP calls.
Deploy to AWS
infra/ is an AWS CDK app that deploys everything as one stack: API Gateway + Lambda (MCP
server and owner API), a Lambda container for the web app, RDS PostgreSQL, Cognito, the outbox
worker on an EventBridge schedule, a Bedrock Knowledge Base, and migrations that run on every
deploy. Architecture and trade-offs: docs/DECISIONS.md (D39).
pnpm install
cd infra
npx cdk bootstrap # once per account/region
npx cdk deploy \
-c ownerBootstrap=you@example.com:fade-studio \
-c sesFromEmail=you@example.com # optional: SES sender (verify the email when asked)
# add -c sesIdentityExists=true if that email is already a verified SES identityRequirements: AWS credentials, Docker (to build the web image), Bedrock access to Claude Haiku
4.5 in the region (default us-east-1). Outputs: WebUrl (dashboard + /assistant),
McpEndpoint, McpDirectoryEndpoint (register this one with the Alexa+ MCP Toolkit),
CognitoDomain, AlexaClientId. Sign up on the web URL with the ownerBootstrap email to manage
Fade Studio. npx cdk destroy removes it all (the database leaves a final snapshot).
What it costs (us-east-1, on-demand, from the AWS Price List API, September 2026)
Always-on baseline, before any traffic:
Resource | Price | Per month |
RDS PostgreSQL db.t4g.micro, single-AZ | $0.016/hour | $11.68 |
RDS gp3 storage, 20 GB | $0.115/GB-month | $2.30 |
NAT instance t4g.micro | $0.0084/hour | $6.13 |
Public IPv4 address (NAT instance) | $0.005/hour | $3.65 |
Secrets Manager, 2 secrets | $0.40/secret | $0.80 |
Bedrock Knowledge Base index storage | $5.00/GB-month (policy documents are kilobytes) | ~$0.00 |
CloudWatch Logs, ECR image, S3, SSM | small | < $1 |
Baseline | ≈ $25–26 |
Per use:
What | Price | Example |
Claude Haiku 4.5 on Bedrock (US cross-region) | $1.10 / M input tokens, $5.50 / M output; cache reads $0.11 / M | One spoken turn ≈ 2–3 model calls ≈ 5–14k input tokens → ≈ $0.01–0.02; a full booking conversation ≈ $0.05 |
Amazon Location Service | Geocode (Core) $0.50 / 1,000; Search Text with contact details (Advanced) $1.50 / 1,000 | One "barber near Williamsburg" search ≈ $0.002 |
Knowledge Base retrieval | $1.00 / 1,000 Retrieve calls | per FAQ question ≈ $0.001 |
API Gateway HTTP API | $1.00 / million requests | negligible |
Lambda (arm64) | $0.20 / million requests + $0.0000133 / GB-second | negligible at demo scale |
Cognito Lite | first 10,000 monthly active users free, then $0.0055 / MAU | $0 for a demo |
SES email | $0.16 / 1,000 emails (plan-dependent) | negligible |
A hackathon month with a few hundred test conversations comes to roughly $25–35. Deleting the stack stops all charges except the final database snapshot (~$0.095/GB-month). The Knowledge Base prices are from the Bedrock pricing page; everything else is from the AWS Price List API.
Development
npm install -g pnpm@10 # or: corepack enable (needs admin rights on Windows)
pnpm install
cp .env.example .env
docker compose up -d # Postgres + migrations + seed
pnpm test # unit + integration tests (starts its own Postgres via Testcontainers)
pnpm lint && pnpm typecheck && pnpm format:check
pnpm db:migrate # apply migrations to DATABASE_URL
pnpm db:seed # seed DATABASE_URL (add -- --reset to reseed)Integration tests need Docker. To use an existing Postgres instead, set TEST_DATABASE_URL to
an admin connection string (the user must be allowed to CREATE DATABASE).
Repository layout
apps/
mcp-server/ # MCP server (+ owner REST API): Hono, MCP SDK v2, OAuth resource server
web/ # Next.js: /assistant (simulated Alexa+) and /dashboard (owners)
worker/ # Outbox delivery (email, SMS, Google Calendar) and maintenance sweeps
packages/
db/ # SQL migrations, migration runner, Kysely types, seed, test helpers
core/ # Domain logic: availability, holds, bookings, policies, store finder
notifications/ # SES / End User Messaging / Google Calendar clients, templates
shared/ # Zod schemas and types shared across apps
infra/ # AWS CDK stack
docs/
ARCHITECTURE.md # Components, request flows, data integrity, deployment
MCP_TOOLS.md # Every tool: description, inputs, outputs, examples, errors
DEMO_SCRIPT.md # The 3-minute demo, line by line
PRODUCT_FEEDBACK.md # Feedback on Bedrock and the other AWS services used
DECISIONS.md # Architecture decisions and deviations from the brief
FRICTION_LOG.md # Every tool/SDK/doc problem hit while buildingData integrity
All instants are stored as timestamptz in UTC. Each business has an IANA time zone, validated
by a trigger, and working hours are local wall-clock times in that zone.
Guarantee | Enforced by |
No two confirmed bookings for the same staff member overlap |
|
No two active holds for the same staff member overlap | Same, on |
Buffers after an appointment are respected | Constraints run on |
A hold becomes at most one booking |
|
Idempotency keys are unique per business |
|
No cross-tenant references | Composite foreign keys on |
Tested directly: 20 concurrent inserts for the same slot result in exactly one booking.
License
This server cannot be deployed
Maintenance
Related MCP Connectors
- AstrocalOAuthdev.astrocal
AI-native scheduling: check availability, book meetings, cancel and reschedule via MCP
Give AI agents a phone number. Voice calls, SMS, and phone number management for MCP clients.
AI agent platform: manage leads, conversations, bots, calendar and CRM via MCP.
Verified local businesses, bookable by AI agents: services, prices, availability and appointments.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn 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.-
- AlicenseNot gradedqualityDmaintenanceEnables users to manage medical appointments by searching for doctors, checking availability, and booking sessions through a natural language interface. It serves as a reference implementation for advanced MCP features like symptom-based specialist recommendations and multi-step scheduling workflows.6 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables natural language interaction with SimplyBook.me API to manage bookings, services, and performers through MCP.2-
- AlicenseNot gradedqualityCmaintenanceExposes the Appointment Scheduler API to AI agents as an MCP server, enabling them to list users and services, check availability, book, list, and cancel appointments via natural language.Apache 2.0