UNC LibCal MCP
UNC LibCal MCP lets AI agents find and book UNC Davis Library study spaces via LibCal, with availability checks that need no login and confirmed bookings using a saved Onyen session.
Check whether your saved LibCal login session is still valid (
libcal_auth_status)Get ranked booking options with same-day priority (
libcal_suggest)Check open slots on a specific date, category, time, and duration (
libcal_check_availability)Book a specific slot only after explicit user confirmation (
libcal_book)Add bookings to Apple Calendar and list available calendars (
libcal_list_calendars)Support multiple space categories: Davis cubes, study rooms, and data services computers
Follow a required workflow: suggest first for open-ended requests, then book only after the user picks and confirms a slot
Adds confirmed LibCal study space bookings to Apple Calendar on macOS via AppleScript, optionally syncing reservation details to the user's chosen calendar.
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., "@UNC LibCal MCPBook me a Davis cube tomorrow at 2pm"
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.
UNC LibCal MCP
MCP server for booking UNC Davis Library study spaces from Claude, Cursor, Codex, or any MCP client.
Built for UNC students, faculty, and staff with a valid Onyen. Not affiliated with or endorsed by UNC Libraries.
What it does
Ask your agent:
Book me a Davis cube tomorrow at 2pm
The server will:
Check LibCal availability (public API — no login needed)
Suggest ranked options (
libcal_suggest) or book a slot you confirm (libcal_book)Complete the reservation in your browser session (Playwright + saved Onyen login)
Related MCP server: @aiwerk/mcp-server-cal
Requirements
Node.js 20+
UNC Onyen (for booking; availability checks work without login)
Chromium (installed automatically via Playwright)
Quick start
Already on this machine?
If you already have the repo and ~/.unc-libcal/:
cd ~/Projects/unc-libcal-mcp # or wherever you cloned it
npm run build
npm test~/Projects/unc-libcal-mcp— the project (clone from GitHub)~/.unc-libcal/— your private session + config (never commit this)browser-profile/— persistent Chromium profile (keeps SSO cookies alive between bookings)storage-state.json— backup cookie export (legacy; auto-migrated on first use)
Skip to step 2 if you've logged in before, or re-run login if booking fails.
1. Clone and install
git clone https://github.com/Thespaceblade/unc-libcal-mcp.git
cd unc-libcal-mcp
npm install
npx playwright install chromium
npm run build
npm test2. Log in to LibCal
npm run loginA browser opens to the Davis cubes page (public — no Onyen prompt until you click a slot).
Manual steps in the browser:
Click any open slot → pick an end time → Submit Times
Sign in with Onyen (+ Duo)
Wait until you see Logout on LibCal
Do not click "Submit my Booking" on the checkout page — that completes a real reservation. Press Enter in the terminal once Logout appears.
Your session is saved to ~/.unc-libcal/browser-profile/ (never commit this). LibCal's auth_id token typically lasts ~24 hours; UNC SSO may expire sooner after inactivity — re-run npm run login when libcal_auth_status reports expired.
3. Configure (optional)
On first run, ~/.unc-libcal/config.json is created with defaults:
{
"defaultCategory": "davis-cubes",
"preferSameDay": true,
"minLeadMinutes": 30,
"searchHorizonDays": 7,
"bookingPurpose": "Study session"
}4. Connect your MCP client
Every client needs the absolute path to dist/index.js. From inside the repo:
pwd # e.g. /Users/you/projects/unc-libcal-mcp
# Use: <that-path>/dist/index.jsOr one-liner:
node -e "const p=require('path'); console.log(p.join(process.cwd(),'dist/index.js'))"All clients below run the same stdio server:
{
"command": "node",
"args": ["/absolute/path/to/unc-libcal-mcp/dist/index.js"]
}Restart the client after editing config.
Claude Desktop
File: ~/Library/Application Support/Claude/claude_desktop_config.json
If the file is new or empty, paste:
{
"mcpServers": {
"unc-libcal": {
"command": "node",
"args": ["/absolute/path/to/unc-libcal-mcp/dist/index.js"]
}
}
}If the file already has other keys (e.g. preferences, coworkUserFilesPath), add only the unc-libcal block inside the existing mcpServers object — do not replace the whole file.
Fully quit and reopen Claude Desktop (Cmd+Q, not just closing the window).
Cursor
Option A — UI: Settings → MCP → Add server → paste the JSON block above.
Option B — project file: .cursor/mcp.json in this repo (good for sharing with teammates):
{
"mcpServers": {
"unc-libcal": {
"command": "node",
"args": ["./dist/index.js"]
}
}
}Use ./dist/index.js only if Cursor's MCP cwd is the project root; otherwise use the absolute path.
OpenAI Codex (CLI)
Codex uses TOML, not JSON. File: ~/.codex/config.toml (or .codex/config.toml in a trusted project).
[mcp_servers.unc-libcal]
command = "node"
args = ["/absolute/path/to/unc-libcal-mcp/dist/index.js"]Or via CLI:
codex mcp add unc-libcal -- node /absolute/path/to/unc-libcal-mcp/dist/index.js
codex mcp list # verify it appearsIf servers don't show up, confirm the project is trusted (codex trust in the repo) when using a project-local .codex/config.toml.
Claude Code (CLI)
File: ~/.claude.json (global) or .mcp.json in the project:
{
"mcpServers": {
"unc-libcal": {
"command": "node",
"args": ["/absolute/path/to/unc-libcal-mcp/dist/index.js"]
}
}
}In a Claude Code session, run /mcp to confirm tools are loaded.
Other MCP clients
Any client that supports stdio MCP can use the same command + args. Point it at dist/index.js after npm run build.
5. Verify it works
In your agent, try:
Check libcal auth statusThen:
Suggest Davis cubes for 2 hours tomorrowYou should see libcal_auth_status, libcal_suggest, libcal_check_availability, and libcal_book available once the server is connected.
Troubleshooting
Problem | Fix |
| Normal. Click a slot → Submit Times → Onyen login. Do not click Submit my Booking |
Accidental booking during login | Cancel via the link in your confirmation email from |
| Run |
Session expires quickly | Normal for UNC SSO — the MCP now reuses one browser profile instead of relaunching fresh browsers each call. Re-login if needed. |
Login saved but booking redirects to SSO | Re-run |
| Slot was taken — run |
MCP tools don't appear in Claude Desktop | Fully quit (Cmd+Q) and reopen; confirm |
Sessions expire periodically (LibCal auth ~24h; UNC SSO sooner with inactivity). Run npm run login again when libcal_auth_status reports expired.
MCP tools
Tool | Login required | Purpose |
| No | Ranked booking options; same-day priority unless you specify a date |
| No | Open slots on one date |
| Yes | Book a confirmed slot |
| Yes | Check if saved session is still valid |
Booking workflow
For open-ended requests (“book a cube”, “max hours”) → agent calls
libcal_suggestfirstAgent shows numbered options; you pick one
Agent calls
libcal_bookwithuser_confirmed: trueand the chosen date/time
libcal_book will not run without explicit confirmation.
Space categories
ID | Description |
| Davis Collaboration Cubes (default) |
| Davis group study rooms |
| Data Services lab computers |
Example prompts
Book me a study room for as long as possible
→ libcal_suggest shows TODAY vs later; you pick; then libcal_book
Book me a Davis cube tomorrow 11am–1pm
→ libcal_suggest or direct libcal_book with your exact time
Any study rooms free Friday afternoon?
→ libcal_check_availability or libcal_suggestHow it works
Availability — reverse-engineered LibCal grid API (
/spaces/availability/grid)Booking — Playwright drives the real LibCal UI: select slot → submit times →
/spaces/authcheckout → confirm form
CLI scripts
# Refresh Onyen session
npm run login
# Run unit tests (46 tests)
npm test
# Book via CLI (uses saved session)
node dist/scripts/run-task.js --date 2026-09-01 --start 14:00 --duration 120Cancelling bookings
This MCP server cannot cancel reservations. LibCal does not expose cancel links in the web UI or any API we can call.
To cancel, use the link in your confirmation email from alerts@mail.libcal.com. Search your inbox for that sender if you need an old booking.
LibCal limits (UNC Davis)
Up to 3 hours per day, in 30-minute / 1-hour segments
Popular slots can be taken between suggest and book
Cubes may require a “course or group name” on the checkout form (defaults to
bookingPurposein config)
Development
npm run build # compile TypeScript → dist/
npm test # unit + integration tests
npm run dev # build and start MCP server on stdioCaveats
Personal automation tool — use responsibly and follow UNC Library policies
Only tested against
calendar.lib.unc.edu(UNC Chapel Hill)Other LibCal institutions would need different
lid/gidconstants insrc/libcal/constants.ts
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.
Related MCP Servers
- FlicenseAqualityDmaintenanceEnables interaction with the DiSH room booking platform to search availability, create bookings, and manage reservations. It allows AI assistants to handle meeting room logistics directly through natural language commands.3

@aiwerk/mcp-server-calofficial
AlicenseAqualityCmaintenanceConnects AI assistants to Cal.com for managing bookings, event types, and availability through natural language.1260MIT- FlicenseNot gradedqualityDmaintenanceEnables natural language booking and management of rooms in Nexudus coworking spaces, including listing rooms, checking availability, booking, viewing/cancelling bookings, and schedules.
- FlicenseNot gradedqualityDmaintenanceExposes Cal.com scheduling tools to AI agents via MCP, enabling listing event types, checking availability, and managing bookings (create, cancel, reschedule).
Related MCP Connectors
Connects ChatGPT to your Apple Calendar via a local Mac agent + Vercel relay
Calendar API for AI agents: events, availability, Google/Microsoft setup, scheduling, and iCal.
Manage Novacal event types, availability, and bookings.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- 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/Thespaceblade/unc-libcal-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server