An AI-powered assistant that seamlessly manages your meeting room bookings and calendar in one conversation. Simply ask it to book a room, check availability, or schedule meetings. It handles the coordination between DiSH room reservations and Google Calendar automatically.
The meeting room booking website for my office (DiSH) was pretty terrible and made booking recurring meetings difficult and time consuming. I built this agent to save on all the manual time spent block booking meeting rooms. It has so far saved me so much time and I use it every week!
Key Features:
- ποΈ Natural language scheduling β "Book me a room tomorrow at 2pm for an hour"
- π Smart availability checking across rooms and calendars
- π Automatic coordination between room bookings and calendar events
- π¬ Conversational interface with streaming responses
Built with Pydantic AI and the Model Context Protocol (MCP) for extensible tool integration.
- Python 3.12+ with
uvinstalled - Bun for the frontend
- Docker and Docker Compose
- Access to the DiSH MCP repository (set
DISH_MCP_PATHto its root; it must have a.venvwithfastmcpinstalled viauv sync)
# 1. Clone and enter the repository
cd dish-booking-agent
# 2. Copy and configure environment variables
cp example.env .env
# Edit .env with your values (API keys, passwords, etc.)
# 3. Install dependencies
cd backend && uv sync && cd ..
cd frontend && bun install && cd ..
# 4. Start all services
make devThis will start:
- Keycloak (authentication): http://localhost:8080
- Backend API (FastAPI): http://localhost:8000
- Frontend (Next.js): http://localhost:3000
| Command | Description |
|---|---|
make dev |
Start all services (infrastructure + backend + frontend) |
make infra |
Start only Docker services (databases + Keycloak) |
make backend |
Start only the FastAPI backend |
make frontend |
Start only the Next.js frontend |
make stop |
Stop all running services |
make logs |
Tail Docker container logs |
make clean |
Stop services and remove Docker volumes |
make help |
Show available commands |
Copy example.env to .env and configure:
cp example.env .envRequired variables:
| Variable | Description |
|---|---|
KEYCLOAK_POSTGRES_PASSWORD |
Password for Keycloak's database |
KEYCLOAK_BOOTSTRAP_ADMIN_PASSWORD |
Keycloak admin console password |
POSTGRES_PASSWORD |
Password for the user database |
OPENAI_API_KEY |
Your OpenAI API key |
DISH_MCP_PATH |
Absolute path to the DiSH MCP repository |
DISH_COOKIE |
Your DiSH authentication cookie |
TEAM_ID |
Your DiSH team ID |
MEMBER_ID |
Your DiSH member ID |
GOOGLE_OAUTH_CREDENTIALS |
Path to Google OAuth JSON for Calendar MCP |
The backend also reads from backend/.env for additional settings. See backend/example.env for reference.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend (Next.js) β
β http://localhost:3000 β
βββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Backend API (FastAPI) β
β http://localhost:8000 β
β βββββββββββββββ βββββββββββββββ βββββββββββββββββββββββββββ β
β β Pydantic AI β β DiSH MCP β β Google Calendar MCP β β
β β Agent ββββ (rooms) β β (calendar events) β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββΌββββββββββββββββββββββββ
βΌ βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β Keycloak β β Keycloak DB β β User DB β
β (port 8080) β β (PostgreSQL) β β (port 5433) β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
GET /health- Health checkGET /send-message?message=<msg>&session=<id>- Send a message to the AI agent
The session parameter maintains separate conversational histories.
cd backend
uv run src/agent.pymake infra # Start databases first
make backendmake frontend- "List my calendar events tomorrow morning."
- "Book a room from 14:00β15:00 tomorrow and create a calendar invite for it."
- "Reschedule the 13:00 sync to 15:00 and keep the same attendees."
- "What rooms are available next Monday afternoon?"
- Ensure Docker is running
- Check that ports 3000, 5433, 8000, and 8080 are not in use
- Verify your
.envfile has all required variables set
# Check if databases are healthy
docker compose ps
# View database logs
docker compose logs user-db
docker compose logs keycloak-dbmake clean # Stops services and removes volumes
make dev # Fresh startThe backend includes unit tests located in backend/tests/. Run them with:
cd backend
uv run pytestNote: The unit tests were generated using Claude Opus 4.5 in the absence of time to write them manually. Whilst they provide some coverage and are better than no tests at all, they should not be fully relied upon and may require review or refinement for production use.
- Start all services with
make dev - Navigate to http://localhost:3000
- Authenticate via Keycloak
- Ask for upcoming events on a given day
- Book a DiSH room and request a matching Google Calendar invite
- Reschedule or cancel events to verify the integration


