io.github.open-deltat/deltat
Give an agent a calendar it can book without double-booking: find, hold, then commit atomically.
Installation
Ajoutez ceci à la configuration MCP de votre client (Claude Desktop : claude_desktop_config.json ; Cursor : .cursor/mcp.json ; VS Code et les autres utilisent la même forme « mcpServers »).
@open-deltat/mcpclaude mcp add deltat -e 'DELTAT_PASSWORD=<your deltat_password>' -e 'DELTAT_HOST=localhost' -e 'DELTAT_PORT=5433' -e 'DELTAT_DATABASE=public' -e 'DELTAT_USER=user' -e 'DELTAT_TLS=<DELTAT_TLS>' -e 'DELTAT_TLS_CA=<DELTAT_TLS_CA>' -- npx -y @open-deltat/mcp@0.2.0
{
"mcpServers": {
"deltat": {
"command": "npx",
"args": [
"-y",
"@open-deltat/mcp@0.2.0"
],
"env": {
"DELTAT_PASSWORD": "<your deltat_password>",
"DELTAT_HOST": "localhost",
"DELTAT_PORT": "5433",
"DELTAT_DATABASE": "public",
"DELTAT_USER": "user",
"DELTAT_TLS": "<DELTAT_TLS>",
"DELTAT_TLS_CA": "<DELTAT_TLS_CA>"
}
}
}
}
Variables d'environnement
DELTAT_PASSWORDobligatoire secret Password for the deltat server. Required; there is no default.DELTAT_HOSTHostname of the deltat server.DELTAT_PORTPort deltat listens on.DELTAT_DATABASETenant to connect to. Each database name is an isolated tenant.DELTAT_USERUsername presented at connect time.DELTAT_TLSon to encrypt the connection and verify deltat's certificate. Unset means off unless DELTAT_TLS_CA is set; without TLS the password is sent in the clear, so use it for any deltat that is not on this machine.DELTAT_TLS_CAPath to a PEM certificate to trust instead of the system's authorities, for a deltat with a self-signed certificate. Implies DELTAT_TLS=on.
Documentation
Tirée du README du projet sur GitHub, actualisée chaque semaine. Les liens ouvrent GitHub.
Sommaire
TAP is the Time Allocation Protocol, an open standard for scheduling, booking, and availability: one shared way to describe time and ask "what is free, and can I claim it before someone else does?", so any app, service, or agent speaks it the same way.
This repo is TAP in practice: its typed TypeScript SDK (@open-deltat/client) and a set of demo apps (seat maps, calendars, capacity pools, recurring schedules, and hold-to-book flows with live updates). The SDK points at deltat, the database built to speak TAP, which treats availability as collision detection on the Unix-time number line. The protocol does not depend on it: any backend that implements TAP can be talked to the same way.
Install
npm install @open-deltat/client
# or: bun add @open-deltat/client
SDK
@open-deltat/client is a typed interface to deltat:
- Resources - hierarchical create / update / delete / get
- Rules - batch
create(items[]), update, delete, get - Bookings - batch
create(items[]), cancel, get with an optional{start, end}window - Holds - place, commit (atomic hold-to-booking conversion), release, get with an optional
{start, end}window - Availability - single-resource and combined multi-resource queries
- Events - real-time LISTEN/NOTIFY subscriptions
expandRecurrence()- turn a recurring pattern (days of week, time range, date range, exclusions) into concrete rule segments, DST-safe in an explicit IANAtimeZone(default UTC)
import { DeltaT, expandRecurrence } from "@open-deltat/client";
const dt = new DeltaT({ host: "localhost", port: 5433 });
const room = await dt.resources.create({ name: "Room A" });
// Open weekdays 9 to 5 for the first quarter, as concrete rules. Wall-clock times are
// interpreted in the given IANA timeZone (default "UTC") and stay correct across DST.
const segments = expandRecurrence({
daysOfWeek: [1, 2, 3, 4, 5],
startTime: "09:00",
endTime: "17:00",
fromDate: "2025-01-01",
toDate: "2025-03-31",
timeZone: "Europe/Berlin",
});
await dt.rules.create(segments.map((s) => ({ resourceId: room.id, ...s })));
const slots = await dt.availability.get({
resourceId: room.id,
start: Date.now(),
end: Date.now() + 86_400_000,
});
deltat's current transport is the PostgreSQL wire protocol, a transitional choice. A v2 framed protocol with HTTP and MCP adapters is planned (see deltat's
docs/REQUIREMENTS.md, PROTO-01/02). The typed API above is built to outlast that swap.
CLI
@open-deltat/cli puts the same booking loop in a terminal, for people and for agents that have a shell. deltat-cli watch <calendar> --json prints one line per change as it happens, so an agent can react to a time being held, booked or freed. See packages/cli.
npm install -g @open-deltat/cli
deltat-cli find <calendar> --from 2026-10-01T09:00:00+02:00 --to 2026-10-01T18:00:00+02:00
Demos
| Demo | What it shows |
|---|---|
| Airline | Split-screen dual-client seat booking with real-time holds |
| Theater | Single-venue seat map with section pricing |
| Stadium | Large-venue seat selection with timed events |
| Calendar | Resource management with weekly and daily views and recurring rules |
| Scheduling | Multi-resource availability finder with threshold modes |
| Availability | Calendly-style owner and booker flow with hold-to-confirm |
| Restaurant | Party size to floor plan to time slot to reservation |
| Parking | Multi-floor garage with zone grids and duration-based booking |
Every demo uses a WebSocket for live updates. The hold-based ones follow a connection-lifecycle pattern: opening a socket places a hold, sending {type: "confirm"} converts it into a booking, and closing the socket releases it. (The demo server still confirms with a release-then-book two-step; it moves to the SDK's atomic holds.commit once a deltat release ships the commit surface.)
Run the demos
Requires Bun.
cd demo
bun install
bun dev # starts deltat and the Next.js dev server
The dev script installs deltat via cargo install if it is missing or out of date.
Repository
packages/client/ @open-deltat/client, the TypeScript SDK over deltat's wire protocol
packages/examples/ @open-deltat/examples, the booking modules (components + "use server" actions) shared by every app
packages/shared/ date and week helpers shared by the apps
demo/ Next.js gallery of the interactive examples above
calendar/ standalone booking app with env-based owner login
Shared examples package
The booking demos are not welded to the demo site. Every example, its React components, its "use server" actions, the deltat client, the seed and booking helpers, and the shared booker UI, lives in one workspace package: @open-deltat/examples. Two kinds of app consume the same package with no duplication:
demo/renders them as a gallery (delt.at). It stays a pure gallery: it shows the examples, it never becomes one of them.- A standalone app (see below) imports the same modules as its own booking surface and adds its own chrome, login, and tenant.
The package ships raw source that carries "use client" / "use server" directives, so a consuming Next.js app must transpile it:
// next.config.ts
export default { transpilePackages: ["@open-deltat/examples"] };
Then import a whole example, or the pieces beneath it, by subpath:
import Gym from "@open-deltat/examples/gym"; // a full example component
import { Stage } from "@open-deltat/examples/components/stage"; // shared booker UI
import { dt } from "@open-deltat/examples/lib/deltat"; // the deltat client
import { enabledExampleIds } from "@open-deltat/examples/config";
Deploying a standalone app with env-based auth
calendar/ is the reference for a single-tenant deployable app: a public booking page plus an owner dashboard behind a login. It needs no user database and no identity provider. The owner credentials, the cookie-signing secret, and the deltat tenant all come from the environment, so a deployment is one image plus its env.
Login model. One operator signs in with CAL_USER / CAL_PASS. On success the app sets an httpOnly session cookie signed with CAL_SECRET (HMAC-SHA256, constant-time verified, with a 7-day server-enforced expiry so a copied cookie still ages out). There is no user table. Every authenticated Server Action calls requireSession() as its first line, because a Server Action is an independent POST endpoint that a layout redirect does not protect.
Environment.
| Variable | Purpose |
|---|---|
CAL_USER, CAL_PASS | owner login credentials |
CAL_SECRET | HMAC key that signs the session cookie |
CAL_DISPLAY_NAME, CAL_SLUG | public business name and booking path (/book/<slug>) |
DELTAT_HOST, DELTAT_PORT, DELTAT_PASSWORD | the deltat instance to talk to |
DELTAT_DB | this deployment's tenant, its isolated data |
Production safety. In production the app refuses to authenticate while CAL_PASS, CAL_SECRET, or DELTAT_PASSWORD are still the in-repo defaults (assertProductionSecrets()), so a deploy can never ship a forgeable session or a public database password.
Example. Build a standalone image from calendar/ (Next server output, the way demo/ does), then run it with this deployment's env and tenant:
services:
fitflow:
image: your-registry/tap-calendar:latest # built from calendar/
environment:
CAL_USER: owner
CAL_PASS: ${CAL_PASS} # from a secret store, never committed
CAL_SECRET: ${CAL_SECRET} # e.g. openssl rand -hex 32
CAL_DISPLAY_NAME: "FitFlow Studio"
CAL_SLUG: fitflow
DELTAT_HOST: deltat
DELTAT_PORT: "5433"
DELTAT_DB: fitflow # this tenant's isolated store
DELTAT_PASSWORD: ${DELTAT_PASSWORD}
ports: ["3000:3000"]
Point DELTAT_DB at a distinct database name per deployment and deltat provisions an isolated store on first connect, so two operators never share data. Generate CAL_SECRET with openssl rand -hex 32 and keep it in your secret store, never in the compose file.
License
Licensed by directory:
- SDK and shared helpers (
packages/): MIT. Use them anywhere, in any project, open or closed. This is what the npm package ships under. - Applications (
demo/,calendar/): AGPL-3.0-or-later. They are meant to be self-hosted and deployed; if you run a modified version as a network service, you must offer that version's source under the same license.
GitHub shows the root MIT license in the sidebar because it only reads the top-level file; the AGPL applies to the app directories regardless, via their own LICENSE files.
Questions fréquentes
Qu'est-ce que io.github.open-deltat/deltat ?
Give an agent a calendar it can book without double-booking: find, hold, then commit atomically.
Comment installer io.github.open-deltat/deltat ?
Il s'exécute sur votre machine. Dans Claude Code : claude mcp add deltat -e 'DELTAT_PASSWORD=<your deltat_password>' -e 'DELTAT_HOST=localhost' -e 'DELTAT_PORT=5433' -e 'DELTAT_DATABASE=public' -e 'DELTAT_USER=user' -e 'DELTAT_TLS=<DELTAT_TLS>' -e 'DELTAT_TLS_CA=<DELTAT_TLS_CA>' -- npx -y @open-deltat/mcp@0.2.0. Pour les autres clients, collez la configuration JSON de cette page dans leurs réglages MCP.
Faut-il une clé API pour io.github.open-deltat/deltat ?
Oui. Il attend DELTAT_PASSWORD, à renseigner dans sa configuration.
io.github.open-deltat/deltat est-il open source ?
Oui. Son code est sur GitHub sous licence MIT.
Qui maintient io.github.open-deltat/deltat ?
Il est publié par open-deltat. AI.tn le référence sans le maintenir ni le recommander.
Issu du registre MCP officiel. Être listé n'est pas une recommandation : vérifiez le code et les permissions d'un serveur avant de lui donner accès à vos données.