Skip to main content
Glama

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:

  1. Check LibCal availability (public API — no login needed)

  2. Suggest ranked options (libcal_suggest) or book a slot you confirm (libcal_book)

  3. 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 test

2. Log in to LibCal

npm run login

A browser opens to the Davis cubes page (public — no Onyen prompt until you click a slot).

Manual steps in the browser:

  1. Click any open slot → pick an end time → Submit Times

  2. Sign in with Onyen (+ Duo)

  3. 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.js

Or 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 appears

If 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 status

Then:

Suggest Davis cubes for 2 hours tomorrow

You should see libcal_auth_status, libcal_suggest, libcal_check_availability, and libcal_book available once the server is connected.

Troubleshooting

Problem

Fix

npm run login opens cubes page, no Onyen prompt

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 alerts@mail.libcal.com

libcal_auth_status says not logged in

Run npm run login (see above). Check authIdExpires in the status response.

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 npm run login — you pressed Enter before seeing Logout

libcal_book fails after suggest

Slot was taken — run libcal_suggest again

MCP tools don't appear in Claude Desktop

Fully quit (Cmd+Q) and reopen; confirm mcpServers path points to dist/index.js

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

libcal_suggest

No

Ranked booking options; same-day priority unless you specify a date

libcal_check_availability

No

Open slots on one date

libcal_book

Yes

Book a confirmed slot

libcal_auth_status

Yes

Check if saved session is still valid

Booking workflow

  1. For open-ended requests (“book a cube”, “max hours”) → agent calls libcal_suggest first

  2. Agent shows numbered options; you pick one

  3. Agent calls libcal_book with user_confirmed: true and the chosen date/time

libcal_book will not run without explicit confirmation.

Space categories

ID

Description

davis-cubes

Davis Collaboration Cubes (default)

davis-study-rooms

Davis group study rooms

davis-computers

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_suggest

How it works

  • Availability — reverse-engineered LibCal grid API (/spaces/availability/grid)

  • Booking — Playwright drives the real LibCal UI: select slot → submit times → /spaces/auth checkout → 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 120

Cancelling 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 bookingPurpose in config)

Development

npm run build    # compile TypeScript → dist/
npm test         # unit + integration tests
npm run dev      # build and start MCP server on stdio

Caveats

  • 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/gid constants in src/libcal/constants.ts

License

MIT — see LICENSE.

A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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