CourtReserve MCP
First MCP server for CourtReserve — the racquet-sports club management platform that runs tennis, pickleball, padel, racquetball, squash, and badminton clubs. Talk to your club's members, reservations, events, and transactions from Claude, Cursor, or any MCP-compatible AI client.
What you can do with it
You: "Find every active member at our downtown location whose membership
expires this month and tell me which ones haven't booked a court
in the last 30 days."
Claude: *calls list_memberships + list_reservations, joins the results, replies*
You: "Register Sarah for the Tuesday evening pickleball clinic."
Claude: *calls register_for_event, confirms the result*
You: "Cancel reservation 8888 and refund the booking fee."
Claude: *calls cancel_reservation + create_transaction (credit), reports back*
The MCP covers the same surface CourtReserve uses internally: members, memberships, families, court reservations, events (clinics, lessons, tournaments, round robins, open play), event registrations, transactions, courts, and locations.
Install
pip install -e .
For local development:
pip install -e ".[dev]"
Configure
CourtReserve's API uses HTTP Basic auth with two values issued from the club admin UI:
- Log in to
app.courtreserve.comas a club admin. - Go to Settings -> Additional Features -> Integrations -> API Access.
- Click Create API Key. Enable the API access checkbox first if it's off.
- Choose Full Access (read + write) or Restricted Access (pick specific roles).
- Copy the Username (format:
Org_<numeric>) and Password (long opaque string).
export COURTRESERVE_USERNAME="Org_12345"
export COURTRESERVE_PASSWORD="98765_550e8400-e29b-41d4-a716-446655440000"
The API key must be enabled on an Advance / Momentum / Enterprise plan (per CourtReserve's docs, the API add-on is paid). The key's role-based permissions control which endpoints the MCP can call.
Claude Desktop / Cursor
Add to your claude_desktop_config.json (or ~/.cursor/mcp.json):
{
"mcpServers": {
"courtreserve": {
"command": "courtreserve-mcp",
"env": {
"COURTRESERVE_USERNAME": "Org_12345",
"COURTRESERVE_PASSWORD": "your-password"
}
}
}
}
Tools (22)
| Group | Tool | Purpose |
|---|---|---|
| Diagnostic | health_check |
Verify credentials + returns locations list |
| Members | list_members, get_member, create_member, update_member, delete_member |
Member CRUD + search |
| Memberships | list_memberships, get_membership, create_membership, update_membership, cancel_membership |
Tier assignment + lifecycle |
| Families | list_families, get_family, add_family_member |
Linked-member accounts |
| Reservations | list_reservations, get_reservation, create_reservation, cancel_reservation |
Court bookings |
| Events | list_events, get_event, list_event_registrations, register_for_event, cancel_event_registration |
Clinics, tournaments, lessons, round robins |
| Transactions | list_transactions, get_transaction |
Payments, credits, refunds |
| Courts | list_courts, get_court |
Court surface + rate info |
| Locations | list_locations, get_location |
Sites/branches |
Run courtreserve-mcp --help (or start the server and inspect tools/list from your client) for the full JSON schema.
Engineering standards
This MCP inherits the engineering playbook applied across the sanjibani MCP portfolio:
- Shared
httpx.AsyncClientwith connection pooling + transport-level retries. - Typed exception hierarchy (
CourtReserveAuthError,NotFoundError,RateLimitError,APIError,ConnectionError) with structured fields (http_status,request_id,retry_after). - Application-level retry with exponential backoff + full jitter on 429/5xx, honoring
Retry-After. - isError-compliance (per the Blackwell Systems MCP security audit): tools
raiseexceptions, FastMCP wraps them withisError=trueon the wire. AI agents can distinguish failures from successful responses returning error-shaped strings. - JSONL audit logging via
src/courtreserve_mcp/audit.py— one record per tool call to stderr (or<PKG>_AUDIT_LOGfile). Fail-open: sink failure never breaks the tool. Secret redaction onpassword/api_key/token/etc. - respx for httpx mocking + hypothesis property tests + pytest-asyncio.
- mypy --strict clean, ruff full rule set clean, py.typed marker (PEP 561).
src/layout, dynamic version from__init__.py, hatchling backend.
Development
pip install -e ".[dev]"
# Lint
ruff check src tests
ruff format --check src tests
# Type
mypy src
# Test
pytest
# All three
ruff check src tests && ruff format --check src tests && mypy src && pytest
License
MIT — see LICENSE.
Author
Sanjibani Choudhury [email protected]. Independent community build — not affiliated with CourtReserve or Storable. PRs welcome if CourtReserve renames an endpoint; open an issue if you find a gap in coverage.
This MCP is part of the sanjibani MCP portfolio — 28+ vertical-specific MCPs (insurance, dental, veterinary, legal, home service, church, auto-dealership, title/escrow, pest control, golf, self-storage, laundromat, youth sports, etc.). All MIT-licensed, all ruff + mypy + pytest clean, all isError-compliant.
Need a custom MCP built for a niche SaaS you use? See engagement options.