Metadata-Version: 2.4
Name: supersaas-slots-mcp
Version: 0.1.1
Summary: Read-only MCP tool for public SuperSaaS resource availability
Author: Richard van den Berg
License-Expression: MIT
Project-URL: Homepage, https://github.com/RichieB2B/supersaas-slots-mcp
Project-URL: Repository, https://github.com/RichieB2B/supersaas-slots-mcp
Project-URL: Issues, https://github.com/RichieB2B/supersaas-slots-mcp/issues
Keywords: mcp,supersaas,scheduling,availability
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Scheduling
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastmcp==4.0.10
Requires-Dist: pydantic<3,>=2
Dynamic: license-file

# SuperSaaS slots MCP server

<!-- mcp-name: io.github.RichieB2B/supersaas-slots-mcp -->

A read-only FastMCP server for public **resource** schedules with one resource and explicit numeric start times. It downloads the public schedule page, extracts `rp_id`, `token`, `bit_prefs`, `open_times`, appointment duration, buffer, and start-time constraints, then calls `/ajax/resource/<rp_id>` in 28-day windows. Each call explicitly requests the exception list with `efrom`, `eto`, and `ed=r`. No account or API key is needed for the tested public page.

Licensed under the [MIT License](LICENSE).

## Install

After publication, use Python 3.10+:

```sh
pip install supersaas-slots-mcp
```

For local development from the project directory:

```sh
python3 -m venv .venv
.venv/bin/python -m pip install -e .
```

Dependencies are declared in `pyproject.toml`; FastMCP is pinned to version 4.0.10. Both `supersaas-slots` and `supersaas-slots-mcp` start the server.

## Connect

Configure a stdio MCP server in your MCP client:

```json
{
  "mcpServers": {
    "supersaas-slots": {
      "command": "/absolute/path/to/supersaas-mcp/.venv/bin/supersaas-slots"
    }
  }
}
```

Replace the command path with the absolute path to your project directory. The client must allow this local process to make HTTPS requests to `www.supersaas.nl` (or `www.supersaas.com`). FastMCP handles the stdio protocol; the availability calculation remains in `supersaas_mcp.py`.

## Tool

`find_available_slots` accepts:

```json
{
  "schedule_url": "https://www.supersaas.nl/schedule/downthehatch/SLEEP",
  "from_date": "2026-10-19",
  "through_date": "2026-10-25"
}
```

`through_date` is inclusive. Optional `max_results` defaults to 500; the response includes the full `count` and `truncated` flag. Optional `respect_booking_window` defaults to `true` and applies the page's minimum and maximum advance-booking limits. Set it to `false` when examining historical schedule data.

Times are returned as schedule wall-clock strings (`YYYY-MM-DD HH:MM`). The schedule's numeric appointment and exception epochs are interpreted as UTC, matching the tested page. The server refreshes the page and AJAX data on each call, so results can change as bookings are made.

For the saved October fixture, the week of October 19 has one free slot: **October 22, 09:30–12:30**. Monday is closed by the low seven bits of `bit_prefs` (`0b1111001`, Sunday first). The October 13 Tuesday exception opens 09:30–12:30.

SuperSaaS selects exception rows by their **start date**. To catch a blocked range that began before the requested window, the AJAX query sets `efrom=1970-01-01` while keeping `eto` at the window's end. Exception type `0` blocks all overlapping dates; type `1` adds the listed opening interval. For example, the live response contains a type `0` block from February 19 through February 28, 2027, so the week of February 22 has **no available slots**.

## Scope

This server handles the tested resource-schedule shape: one resource, fixed duration, up to two daily opening periods, explicit numeric start times, weekday enable bits, additive opening exceptions, blocked ranges, booked appointments, and buffer time. It rejects schedules advertising clustering, synchronization, or complex linked rules. Other SuperSaaS schedule types, recurring rule patterns, per-user limits, and payment-dependent availability are not modeled. An available slot is a calculated candidate, not a booking guarantee; the booking page remains authoritative at reservation time.

## Test

```sh
.venv/bin/python -m unittest -v test_supersaas_mcp.py
```

The tests use the included copies of your example files. A live read-only call against the example schedule also returned the expected October 22 slot on 2026-09-27.

## Release

Releases use [PyPI Trusted Publishing](https://docs.pypi.org/trusted-publishers/using-a-publisher/) and [MCP Registry GitHub OIDC](https://github.com/modelcontextprotocol/registry/blob/main/docs/modelcontextprotocol-io/github-actions.mdx). Before the first release:

1. Create a `pypi` environment in this GitHub repository and allow deployment from version tags. In PyPI, register a pending trusted publisher for owner `RichieB2B`, repository `supersaas-slots-mcp`, workflow `release.yml`, and environment `pypi`. The PyPI project does not need to exist yet.
2. Create an `mcp-registry` GitHub environment and allow deployment from version tags. The Registry uses GitHub OIDC, so it needs no registry token.
3. Keep the version in `pyproject.toml`, `server.json` (both version fields), and the FastMCP server constructor in sync. Commit the release before tagging it.
4. Push a matching tag, for example `git tag v0.1.0 && git push origin v0.1.0`.

The [release workflow](.github/workflows/release.yml) tests and builds the distribution, publishes it to PyPI, then submits `server.json` to the MCP Registry. The [CI workflow](.github/workflows/ci.yml) runs tests and package checks on pushes and pull requests. A pushed release tag publishes externally; review its commit and environment settings first.
