Office Booking MCP
by vamsi-1234
README.md
# Office Booking MCP
A small, **personal** [Model Context Protocol](https://modelcontextprotocol.io)
server **and** command-line tool that books and cancels your office **cab** and
**lunch** from inside VS Code (or any MCP client) — or fully on autopilot — by
wrapping the same APIs the company apps already use with *your own* logged-in
account.
> ⚠️ **Use responsibly.** This only replays requests **your own authenticated
> account** is allowed to make. Don't share captured tokens, don't automate
> other people's accounts, and check your company's acceptable-use policy before
> relying on it. It is not affiliated with or endorsed by the app vendors.
---
## What you get
**Two ways to drive it:**
- **MCP server** — ask an LLM agent (e.g. Copilot Chat) in plain English:
*"book lunch for next Wednesday"*, *"cancel Friday"*, *"list my cab trips"*.
- **CLI** (`office-booking …`) — the same actions from the terminal, also
understands natural-language dates (`book "next wednesday"`, `book "this week"`).
**Core tools:**
| Tool | What it does |
| --------------------- | ------------------------------------ |
| `list_cab_bookings` | Show your current/upcoming cab trips |
| `book_cab` | Book a cab |
| `cancel_cab` | Cancel a cab trip |
| `list_lunch_bookings` | Show your lunch bookings |
| `book_lunch` | Book lunch for a date |
| `cancel_lunch` | Cancel a lunch booking |
**Hands-off extras (lunch):**
- 📅 **Attendance schedule** — encode your rotating hybrid pattern (e.g. a 3-day
week alternating with a 2-day week); it books only the days you're actually in.
- 🏖️ **Outlook leave detection** — reads your Outlook calendar and skips any
day marked *Out of Office* or titled like leave/PTO/vacation.
- 📧 **Daily QR delivery by email** — emails you the day's lunch QR, then deletes
it again in the evening via IMAP so your inbox stays clean.
- 💻 **Wake-triggered auto-booking** — a macOS `launchd` job books every upcoming
office day inside the cafeteria's advance window *whenever your Mac is awake*
(no fixed alarms; idempotent, so it just tops up what's missing).
The endpoints are **not hard-coded to your company** — the project ships with
placeholder paths/payloads marked `TODO`. You fill them in once, using the
traffic you capture in Step 1.
---
## Step 1 — Capture the APIs
> ✅ **Easiest path first: use the web app.** If your cab/lunch service has a
> **web portal**, capture it there — open the site in your browser, press F12 →
> **Network** tab, perform each action once, and copy the requests (right-click →
> *Copy as cURL*). There's **no certificate setup and no TLS pinning** to fight,
> so it's dramatically simpler than intercepting a phone. The project even ships
> a `curl_to_config` helper to turn a pasted cURL command into config. **Only**
> fall back to the mobile-proxy steps below if there is no web version.
If the service is **mobile-only**, intercept its HTTPS traffic with a proxy.
[mitmproxy](https://mitmproxy.org) is free and works well.
### 1a. Install + start mitmproxy
```bash
brew install mitmproxy # macOS
mitmweb # opens a web UI at http://127.0.0.1:8081
```
mitmproxy listens on port **8080** by default.
### 1b. Point your phone at the proxy
1. Put your **phone and Mac on the same Wi-Fi**.
2. Find your Mac's IP: `ipconfig getifaddr en0`.
3. On the phone: **Wi-Fi → (your network) → Configure Proxy → Manual**,
server = your Mac IP, port = **8080**.
### 1c. Install mitmproxy's CA certificate on the phone
1. On the phone's browser open <http://mitm.it> and install the cert for your OS.
2. **iOS:** Settings → General → VPN & Device Management → install the profile,
then **Settings → General → About → Certificate Trust Settings** and toggle
it **on**. (Both steps are required.)
3. **Android:** install under user certificates (system store needs root).
### 1d. The TLS-pinning gotcha ⚠️
Many corporate apps use **certificate pinning** and will refuse to connect while
proxied — you'll see connection errors in the app and TLS errors in mitmproxy.
Things to try, in order of effort:
- **Check if there's a web version** (the recommended path — see the tip at the
top of Step 1). Capturing the web portal in browser DevTools avoids pinning
entirely and is by far the easiest option.
- See whether the app still works for *some* calls (login may be pinned but
booking may not).
- On a **rooted Android / jailbroken iOS** you can disable pinning with Frida +
`objection`, but that's advanced and may violate device/app policy — only do
it on a device you own and are allowed to modify.
If pinning fully blocks you, the web portal route is by far the most practical.
### 1e. Record each action
With capturing live, perform each action **once** in the app:
list trips, book a cab, cancel it, list lunch, book lunch, cancel it.
For each captured request note:
- **Host** (e.g. `cab-api.yourcompany.com`) → goes in `*_API_BASE_URL`
- **HTTP method + path** (e.g. `POST /api/v1/trips`)
- **Auth header** (e.g. `Authorization: Bearer eyJ...`) → token goes in `*_AUTH_TOKEN`
- Any extra header like `x-api-key` → `*_API_KEY`
- The **request body** (JSON) and the **response body**
---
## Step 2 — Fill in the endpoints
Open these two files and replace the `TODO` placeholders with what you captured:
- `src/office_mcp/cab_client.py`
- `src/office_mcp/lunch_client.py`
You're adjusting three things per method: the **HTTP method**, the **path**, and
the **JSON field names**. The auth headers are handled centrally in
`src/office_mcp/http_client.py` (`_default_headers`) — tweak there if your app
doesn't use `Authorization: Bearer`.
---
## Step 3 — Configure secrets
```bash
cp .env.example .env
```
Fill in the base URLs and tokens you captured. `.env` is git-ignored, so your
tokens stay local.
> 🔑 Tokens often expire. When a tool starts returning `HTTP 401`, re-capture a
> fresh token and update `.env`.
---
## Step 4 — Install & run
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
```
Sanity-check it starts (Ctrl-C to stop):
```bash
python -m office_mcp.server
```
---
## Step 5 — Use it in VS Code
This repo includes [`.vscode/mcp.json`](.vscode/mcp.json), so VS Code will offer
to start the **office-booking** server. Open the Copilot Chat **Agent** mode,
and you can ask things like:
- "List my cab bookings."
- "Book a cab from Home to Office tomorrow at 9:30am."
- "Cancel lunch order 12345."
Enable debug logging by setting `OFFICE_MCP_DEBUG=true` in `.env` to see the
exact outgoing requests in the server's stderr.
---
## Step 6 — (Optional) CLI & hands-off automation
The same actions are available from the terminal via the `office-booking`
command (installed by `pip install -e .`):
```bash
office-booking lunch list
office-booking lunch book "next wednesday" # natural-language dates
office-booking lunch cancel <order-id>
office-booking lunch qr 23-06-2026 # generate a booking's QR
```
**Lunch automation commands:**
```bash
office-booking schedule set # record your rotating office-attendance pattern
office-booking lunch auto-book # book upcoming office days in the advance window
office-booking lunch qr-deliver # email today's QR to yourself
office-booking lunch qr-cleanup # delete that QR email via IMAP
```
These are designed to run unattended on macOS via `launchd` agents
(`~/Library/LaunchAgents/com.officebooking.*.plist`):
- **auto-book** — runs whenever the Mac wakes (`RunAtLoad` + a periodic
`StartInterval`); idempotent, so it simply books any still-unbooked office day
inside the cafeteria's advance window and skips leave days.
- **qr-deliver / qr-cleanup** — fixed weekday times; if the Mac is asleep at the
scheduled time, `launchd` runs the missed job shortly after the Mac wakes.
All of these honour the attendance schedule and Outlook leave detection, so you
only ever get booked for days you're actually in the office.
---
## Project layout
```
src/office_mcp/
config.py # loads settings from .env (no secrets in code)
http_client.py # auth + request plumbing, error handling
cab_client.py # cab endpoints ← fill in TODOs
lunch_client.py # lunch endpoints ← fill in TODOs
server.py # MCP server: the booking tools
cli.py # `office-booking` command-line interface
dates.py # natural-language date parsing
attendance.py # rotating office-attendance schedule
outlook_leave.py # reads Outlook for Out-of-Office / leave days
mailer.py # SMTP send + IMAP delete for daily QR delivery
qrcode.py # QR image generation
curl_to_config.py# turn a pasted cURL command into config
update_token.py # refresh an expired auth token in .env
.vscode/mcp.json # VS Code MCP server registration
.env.example # copy to .env and fill in
```
## Security notes
- Secrets live only in `.env` (git-ignored) — never commit real tokens.
- The server makes outbound calls only to the hosts you configure.
- If you push this to a repo, double-check no capture files (`captures/`,
`*.flow`), `.env`, or personal data (`office_schedule.json`, QR PNGs) slipped
in. The included `.gitignore` already excludes all of these.
TDQS
A3.8/5.0
Scored across 6 tools
Disambiguation5/5
Each tool targets a distinct resource (cab or lunch) and action (book, cancel, list), with no overlap or ambiguity.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern (e.g., book_cab, cancel_lunch), making them predictable and easy to understand.
Tool Count5/5
With 6 tools covering two services with three operations each, the count is well-scoped and appropriate for the domain.
Completeness3/5
The set covers create, cancel, and list for both services, but lacks update/modify functionality, requiring users to cancel and rebook for changes, which is a notable gap.
Maintenance
ActivityInactive
ResponsivenessNo issues