Skip to main content

holiplan

An MCP server for planning a family's year around school holidays and a limited leave allowance.

Assistants are good at suggesting destinations and bad at remembering that Whit Monday is a public holiday, that five carried-over days expire in June, and that you already said no drive over three and a half hours. This server does the parts that should be calculated; the assistant does the parts that need judgement.

Holiday data comes from OpenHolidays (CC BY 4.0), which covers public and school holidays for a growing list of countries, with no API key.

Status

Pre-release (0.1). Stateless: your ledger is a JSON file you keep, and the server stores nothing. See PRIVACY.md for exactly what goes where, and docs/examples.md for what a conversation looks like.

Use it in Claude Desktop

Install uv, then add holiplan to claude_desktop_config.json and restart Claude:

{
  "mcpServers": {
    "holiplan": {
      "command": "uvx",
      "args": ["holiplan"]
    }
  }
}

uvx fetches holiplan from PyPI and runs it; there is nothing else to install. Without uv, pip install holiplan and use "command": "holiplan" with no args.

Start with the Set up my family profile prompt, which builds a ledger with you one question at a time, or copy examples/ledger.example.json to my-ledger.json and edit it. Tell Claude where the file is, and save the updated ledger whenever Claude hands it back. A conversation then looks like:

Here's my ledger. What do the 2027 school holidays look like, and what can I afford?

Add two weeks on the Danish coast from 17 July.

What needs booking next?

docs/examples.md has these conversations in full, with real figures.

Tools

Tool Purpose
get_holiday_windows School holidays (official and effective dates), single-day closures, and public holidays marked local, half-day and observed
calculate_leave_cost Leave days a given trip needs, with the holidays inside it listed
find_bridge_days The leave days that buy the most time off, and whether the kids are off too
get_year_budget Planned versus available leave, including carryover expiry
upsert_trip Add or update a trip, then re-check the ledger
check_ledger Overlaps, budget breaches, bad dates, trips outside school holidays
list_deadlines Booking deadlines and cancel-by dates, soonest first
summarise_plan The whole plan at a glance, for a brief to your partner
export_ics The plan as a calendar file

Resources: JSON schemas for the ledger, profile and trip (holiplan://schema/...), and a blank starter ledger (holiplan://ledger/starter).

Prompts: Set up my family profile, Plan my year, Plan this holiday window, What needs doing next?, Make a brief for my partner.

Design notes

  • The ledger is the source of truth. Tools take it in and hand it back, so the plan doesn't drift between conversations.
  • Intent decides leave. A week with intent home or camp occupies a school holiday window without costing leave. Override with takes_leave.
  • Carryover is spent first, but only by trips ending before the expiry date, so "these days expire in June" shows up as a warning while you can still act on it.
  • A trip over New Year costs each year only its own days.
  • Local holidays follow your home town. Some holidays cover only part of a region, like Augsburg's Peace Festival in Bavaria. With the profile's home set to a town, only that town's local holidays count as days off; without a home they all do. Set local_holidays to "include" or "exclude" to override. ignore_holidays ("MM-DD") covers what the data can't tell apart, such as Assumption Day ("08-15"), which is only a holiday in Catholic-majority Bavarian towns.
  • School windows include the free days around them. The official Monday-to-Friday dates are stretched over adjacent weekends and public holidays before trips are checked against them. School holidays of two school days or fewer, like All Souls' Day in Austria, are listed separately as closures.
  • Half-day holidays cost half a day. Zürich's Sechseläuten afternoon is a half day off, not a full one.
  • Regions accept ISO codes. OpenHolidays uses its own codes where they differ (Vienna is AT-WI, not AT-9); either works, and an unknown region is an error rather than a quietly incomplete year.
  • Ledgers are versioned. Older ledgers are migrated when read, a newer one is refused, and a malformed one gets an error naming the trip and field at fault.
  • When OpenHolidays is down, the server serves the last copy it fetched, or says plainly that it can't check dates right now. It never guesses.
  • No real names. Children are identified by alias and interests only.
  • The server never books anything. It knows what needs booking and by when; you book it and record the result.

Roadmap

  • Drive-time filtering (OpenRouteService or self-hosted OSRM)
  • Remote deployment over Streamable HTTP
  • Publish to the MCP registry
  • School holiday windows by school type, where the data supports it (Zürich splits primary, secondary and vocational; windows already list the types they apply to)

Development

git clone https://github.com/adekola/holiplan.git
cd holiplan
python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
python -m unittest discover -s tests                # offline

To run your working copy in Claude Desktop, point command at the venv's Python (.venv/bin/python, or .venv\Scripts\python.exe on Windows) with "args": ["-m", "holiplan.server"].

Licence

MIT, see LICENSE. Holiday data: OpenHolidays, CC BY 4.0.

Metadata

Release files for holiplan 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for holiplan 0.1.0
File Size Uploaded Provenance
holiplan-0.1.0.tar.gz 56.9 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for holiplan 0.1.0
File Interpreter ABI Platform
holiplan-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 87.4 kB

Release files / holiplan-0.1.0.tar.gz

Download URL holiplan-0.1.0.tar.gz
Size 56.9 kB
Tags Source
SHA-256 checksum
How to use checksums
d3bfbe9c57d48960d01dd231c803655efc3dea96ccb00a5f6d58996a59c0114e
BLAKE2b-256 checksum
How to use checksums
ed058291fba672c1d00982f5789bb4328ea9d4fd3c015fb15881a7c2d3f80cd2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.

Transparency log

Release files / holiplan-0.1.0-py3-none-any.whl

Download URL holiplan-0.1.0-py3-none-any.whl
Size 30.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6f1fef5997c7be942f41dd218a4ea345242aec372981b293c14aff041e79395e
BLAKE2b-256 checksum
How to use checksums
5451ab8d25e54483d12f2d21a1946764dee879c1dccda7f82caca3b94c9d74ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.

Transparency log

Security for holiplan 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for holiplan-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page