Mycal
БесплатноНе проверенMalaysia public holidays, school terms, business days & a leave optimizer (13 tools).
Описание
Malaysia public holidays, school terms, business days & a leave optimizer (13 tools).
README
Malaysia's most complete calendar API — public holidays, school calendar, exam schedules, and MCP server for AI tools.
npm: mycal-core npm: mycal-sdk npm: mycal-mcp-server License: MIT Deploys on Cloudflare
Data source: Official government gazette (JPM BKPP), JAKIM, KPM, MPM. Not scraped from third-party websites.
Links
- Website + demo: https://mycal-web.pages.dev
- Developer docs: https://mycal-web.pages.dev/docs
- API base URL: https://mycal-api.huijun00100101.workers.dev/v1
- GitHub: https://github.com/Junhui20/malaysia-calendar-api
Packages
Published to npm under the @catlabtech scope:
| Package | Purpose | Install |
|---|---|---|
| @catlabtech/mycal-core | Shared types, Zod schemas, and calendar/business-day logic | npm install @catlabtech/mycal-core |
| @catlabtech/mycal-sdk | TypeScript client SDK for the REST API | npm install @catlabtech/mycal-sdk |
| @catlabtech/mycal-mcp-server | MCP server exposing 13 calendar tools for AI agents | npm install @catlabtech/mycal-mcp-server |
Features
- 49 public holidays for 2026 from official gazette (Warta Kerajaan) — federal + state-specific
- 16 states + 3 Federal Territories with aliases (KL, JB, Penang, etc.)
- Weekend-aware — Kedah/Kelantan/Terengganu use Fri-Sat (Kumpulan A), all others use Sat-Sun (Kumpulan B), with Johor's historical switch tracked
- Cuti ganti (replacement holiday) auto-calculation per state weekend config
- Business day calculator — per-state, holiday-aware
- School calendar — terms, holidays, KPM cuti perayaan (Lampiran A/B/C)
- Exam schedules — SPM, STPM, MUET, PT3
- iCal subscription feeds — per-state
.icsfeeds - MCP Server for AI agents — 13 tools for Claude, ChatGPT, and other assistants
- TypeScript SDK (
@catlabtech/mycal-sdk) with typed responses - OpenAPI 3.1 spec + interactive docs
- Trilingual — Bahasa Melayu, English, Chinese names (三语支持)
Quick Start
# Clone and install
git clone https://github.com/Junhui20/malaysia-calendar-api.git
cd malaysia-calendar-api
pnpm install
# Build shared packages
pnpm --filter @catlabtech/mycal-core build
pnpm --filter @catlabtech/mycal-sdk build
# Run API locally (http://localhost:8787)
cd packages/api && npx wrangler dev
# Run web site locally (http://localhost:4321)
pnpm --filter @mycal/web dev
# Validate data
pnpm validate
# Run tests
pnpm test
API Examples
Base URL: https://mycal-api.huijun00100101.workers.dev/v1
List holidays
# All holidays for Selangor in 2026
curl "https://mycal-api.huijun00100101.workers.dev/v1/holidays?year=2026&state=selangor"
# Islamic holidays only
curl "https://mycal-api.huijun00100101.workers.dev/v1/holidays?year=2026&type=islamic"
# March holidays for KL
curl "https://mycal-api.huijun00100101.workers.dev/v1/holidays?year=2026&state=KL&month=3"
Check a date
# Is March 21 a holiday/weekend/working day?
curl "https://mycal-api.huijun00100101.workers.dev/v1/holidays/check?date=2026-03-21&state=KL"
Response:
{
"data": {
"date": "2026-03-21",
"dayOfWeek": "Saturday",
"isHoliday": true,
"isWeekend": true,
"isWorkingDay": false,
"isSchoolDay": false,
"holidays": [
{
"id": "2026-hari-raya-aidilfitri-1",
"name": { "ms": "Hari Raya Aidilfitri", "en": "Eid al-Fitr", "zh": "开斋节" },
"type": "islamic",
"status": "confirmed"
}
]
}
}
Business days
# Count working days in March for Selangor
curl "https://mycal-api.huijun00100101.workers.dev/v1/business-days?start=2026-03-01&end=2026-03-31&state=selangor"
# Add 10 business days to a date
curl "https://mycal-api.huijun00100101.workers.dev/v1/business-days/add?date=2026-03-01&days=10&state=selangor"
School calendar
# Is this a school day?
curl "https://mycal-api.huijun00100101.workers.dev/v1/school/is-school-day?date=2026-03-21&state=selangor"
# School holidays for Kumpulan B
curl "https://mycal-api.huijun00100101.workers.dev/v1/school/holidays?year=2026&group=B"
# Exam schedule
curl "https://mycal-api.huijun00100101.workers.dev/v1/school/exams?year=2026&type=spm"
Next holiday
# Next holiday for Penang
curl "https://mycal-api.huijun00100101.workers.dev/v1/holidays/next?state=penang"
State resolution
# Resolve alias
curl "https://mycal-api.huijun00100101.workers.dev/v1/states/resolve?q=kl"
# -> { "data": { "canonical": "kuala-lumpur", "group": "B" } }
Full API Reference
| Endpoint | Description |
|---|---|
GET /v1/holidays |
List holidays (filter by year, state, type, status, month) |
GET /v1/holidays/check |
Is this date a holiday/weekend/working day/school day? |
GET /v1/holidays/today |
Today's holiday status |
GET /v1/holidays/next |
Next upcoming holiday |
GET /v1/holidays/between |
Holidays in date range |
GET /v1/holidays/leave-optimizer |
Suggest annual-leave days to spend for the longest consecutive break |
GET /v1/business-days |
Count business days between dates |
GET /v1/business-days/add |
Add N business days to a date |
GET /v1/states |
All 16 states + 3 FTs with weekend config |
GET /v1/states/resolve |
Resolve alias (KL, penang, jb) to canonical code |
GET /v1/school/terms |
School term dates + day counts |
GET /v1/school/holidays |
School holidays + KPM cuti perayaan |
GET /v1/school/exams |
SPM, STPM, MUET, PT3 schedule |
GET /v1/school/is-school-day |
Is this a school day? |
GET /v1/feed/ical/:state |
iCal subscription feed |
GET /v1/feed/csv/:state |
CSV/spreadsheet export of holidays |
GET /v1/data/* |
Raw, cacheable open-data snapshots — manifest, states, holidays/:year, all (no API key required) |
GET /v1/prayer-times/:zone |
JAKIM prayer times for a zone (MYT-formatted); GET /v1/prayer-times/zones lists the zone directory |
POST /v1/keys |
Issue an API key (admin-gated for now; GET /v1/keys/whoami checks the caller's tier) |
See the full OpenAPI 3.1 spec for request/response schemas.
SDK Usage
import { MyCalClient } from "@catlabtech/mycal-sdk";
const cal = new MyCalClient();
// Check if a date is a working day
const result = await cal.check("2026-03-21", "selangor");
console.log(result.isWorkingDay); // false
// List holidays
const holidays = await cal.holidays({ year: 2026, state: "KL" });
// Business days
const workDays = await cal.businessDays("2026-03-01", "2026-03-31", "selangor");
console.log(workDays.businessDays); // 22
// School calendar
const terms = await cal.school.terms({ year: 2026, group: "B" });
const exams = await cal.school.exams({ year: 2026, type: "spm" });
const isSchool = await cal.school.isSchoolDay("2026-03-21", "selangor");
MCP Server
Connect the Malaysia Calendar API to Claude, ChatGPT, or any MCP-compatible AI assistant.
Setup with Claude Desktop / Claude Code
Add to your MCP configuration:
{
"mcpServers": {
"malaysia-calendar": {
"command": "npx",
"args": ["@catlabtech/mycal-mcp-server"]
}
}
}
Available Tools (13)
| Tool | Description |
|---|---|
get_malaysia_holidays |
Get public holidays (filter by year, state, type) |
check_malaysia_holiday |
Check if a date is a holiday or working day |
next_malaysia_holiday |
Find the next upcoming holiday |
malaysia_business_days |
Count working days between two dates |
malaysia_long_weekends |
Find long weekends (3+ days) |
malaysia_leave_optimizer |
Find the most efficient leave days to take to maximise consecutive days off |
list_malaysia_states |
List all states with weekend config |
resolve_malaysia_state |
Resolve alias (KL, JB) to canonical code |
malaysia_holiday_changes |
Recent data changes |
malaysia_school_terms |
School term dates and day counts |
malaysia_school_holidays |
School holidays (cuti penggal, cuti perayaan) |
malaysia_exams |
SPM, STPM, MUET, PT3 exam schedule |
malaysia_is_school_day |
Check if a date is a school day |
State Codes
| Code | Aliases | Group | Weekend |
|---|---|---|---|
johor |
jhr, jb | B | Sat-Sun (was Fri-Sat 2014-2024) |
kedah |
kd, kdh | A | Fri-Sat |
kelantan |
kel, kb | A | Fri-Sat |
terengganu |
trg, kt | A | Fri-Sat |
perak |
prk, ipoh | B | Sat-Sun |
pulau-pinang |
penang, pg | B | Sat-Sun |
selangor |
sel, sgr | B | Sat-Sun |
negeri-sembilan |
ns, n9 | B | Sat-Sun |
melaka |
mlk, malacca | B | Sat-Sun |
pahang |
phg, kuantan | B | Sat-Sun |
perlis |
pls, kangar | B | Sat-Sun |
sabah |
sbh, kk | B | Sat-Sun |
sarawak |
swk, kuching | B | Sat-Sun |
kuala-lumpur |
kl | B | Sat-Sun |
wp-putrajaya |
putrajaya, pjy | B | Sat-Sun |
wp-labuan |
labuan, lbn | B | Sat-Sun |
State aliases are case-insensitive. Use GET /v1/states/resolve?q=kl to resolve any alias to the canonical code.
Project Structure
malaysia-calendar-api/
├── data/ # JSON data files (source of truth / 数据源)
│ ├── holidays/
│ │ ├── 2024.json # Holiday data per year
│ │ ├── 2025.json
│ │ └── 2026.json
│ ├── school/
│ │ ├── terms-2026.json # School terms (Kumpulan A + B)
│ │ ├── holidays-2026.json # School holidays + KPM cuti perayaan
│ │ └── exams-2026.json # SPM, STPM, MUET, PT3 schedules
│ ├── states.json # 16 states + 3 FT, aliases, weekend history
│ └── known-fixed-holidays.json
├── packages/
│ ├── core/ # Shared business logic (types, schemas, utils)
│ │ └── src/
│ │ ├── types.ts # Holiday, State, SchoolTerm, Exam interfaces
│ │ ├── schemas.ts # Zod validation schemas
│ │ ├── filter.ts # Query filtering logic
│ │ ├── replacement.ts # Cuti ganti calculation
│ │ ├── state-resolver.ts
│ │ ├── business-days.ts
│ │ └── school.ts # School term/holiday/exam logic
│ ├── api/ # Hono API on Cloudflare Workers
│ ├── mcp-server/ # MCP Server (13 tools)
│ ├── sdk/ # TypeScript client SDK (@catlabtech/mycal-sdk)
│ └── web/ # Astro + Starlight — marketing site, demos, docs
├── scripts/
│ ├── validate-data.ts # 5-layer data validation pipeline
│ └── sync-to-kv.ts # JSON -> Cloudflare KV denormalization
├── openapi.yaml # OpenAPI 3.1 spec (spec-first)
├── pnpm-workspace.yaml
└── turbo.json
Data Sources
All data is sourced from official Malaysian government publications:
| Source | Data | URL |
|---|---|---|
| JPM BKPP | Federal Gazette / Warta Kerajaan (public holidays) | kabinet.gov.my |
| JAKIM | Takwim Hijri-Miladi (Islamic calendar) | e-solat.gov.my |
| KPM | Kalendar Akademik / school calendar (Lampiran A/B/C) | moe.gov.my |
| MPM | STPM & MUET exam schedules | mpm.edu.my |
| State Portals | State-specific holidays (16 states) | *.gov.my |
Holiday data includes gazette references (e.g., P.U.(B) 305/2025) for traceability.
Deploy
Two parts deploy independently:
API → Cloudflare Workers
pnpm --filter @catlabtech/mycal-core build
cd packages/api && npx wrangler deploy
Website → Cloudflare Pages
pnpm --filter @catlabtech/mycal-core build
pnpm --filter @catlabtech/mycal-sdk build
pnpm --filter @mycal/web build
# Direct upload via wrangler (requires CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID)
cd packages/web
npx wrangler pages deploy dist --project-name=mycal-web
First-time Pages setup:
- Create a Pages project named
mycal-webin the Cloudflare dashboard. - Either connect the GitHub repo for automatic builds, or rely on the GitHub Actions workflow (
.github/workflows/deploy.yml) to push viawrangler pages deploy. - Required GitHub secrets:
CLOUDFLARE_API_TOKEN,CLOUDFLARE_ACCOUNT_ID.
CI/CD
GitHub Actions handles:
- PR gate — Zod schema validation + cross-source checks on every PR
- Deploy — On merge to
main: build and deploy API to Workers + Web to Pages in parallel - Daily scrape — Government portal monitoring for updates
- Rukyah monitor — Islamic date confirmation tracking
Contributing
See CONTRIBUTING.md for how to:
- Report a missing holiday or cuti peristiwa
- Fix data errors
- Add new features
License
MIT
Установить Mycal в Claude Desktop, Claude Code, Cursor
unyly install mycalСтавит в Claude Desktop, Claude Code, Cursor и VS Code — сам разбирается с npx, uvx и сборкой из исходников.
Впервые? Поставь CLI: curl -fsSL https://unyly.org/install | sh
Или настроить вручную
Выполни в терминале:
claude mcp add mycal -- npx -y @catlabtech/mycal-mcp-serverFAQ
Mycal MCP бесплатный?
Да, Mycal MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Mycal?
Нет, Mycal работает без API-ключей и переменных окружения.
Mycal — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Mycal в Claude Desktop, Claude Code или Cursor?
Открой Mycal на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectCompare Mycal with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
