リポジトリ情報はまだ収集していません。
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Prayer times, iqamah times, and masjid locations for Sheffield, built with Next.js App Router.
/compare)/last-ten) - with saved progress and night switcher/mosques/[slug])/mosques/[slug]/timetable and global /timetable)/mosques/[slug]/ramadan-timetable)adhan (devDep), moment-hijri, custom DST logic>=20.9.0bun install
bun run dev
Create .env.local and set:
NEXT_PUBLIC_SITE_URL=https://your-domain.com
CONVEX_URL=<your-convex-url> # Optional, server only - enables live backend
CONVEX_READ_SECRET=<secret> # Optional, server only - must match CONVEX_READ_SECRET on the Convex deployment
WEBMCP_ORIGIN_TRIAL_TOKEN=<token> # Optional - Chrome WebMCP origin trial
OPENAI_APPS_CHALLENGE_TOKEN=<token> # Optional - OpenAI plugin domain verification
NEXT_PUBLIC_SITE_URL - Used for canonical URLs, robots.txt, and sitemap.xml. Falls back to http://localhost:3000 if unset.CONVEX_URL - Server-only Convex deployment URL. When set, the server reads mosques, monthly prayer times and Ramadan timetables from Convex (pages, /api/prayer-times, /api/mcp, and /api/timetable, which client components use). Browsers never get this URL. Falls back to static JSON in public/data/ if unset or if Convex fails. NEXT_PUBLIC_CONVEX_URL is no longer read by the web app (local scripts still accept it).CONVEX_READ_SECRET - Server-only secret sent as readSecret to Convex reads and to the shared API rate limiter (rateLimits:consume). Separate from ADMIN_SECRET, which must never be set in the web runtime.WEBMCP_ORIGIN_TRIAL_TOKEN - When set, sends an Origin-Trial header so Chrome can enable WebMCP without a local flag. Register at https://developer.chrome.com/origintrials. Local testing also works with chrome://flags/#enable-webmcp-testing.OPENAI_APPS_CHALLENGE_TOKEN - Exact plain-text token from the OpenAI Plugins portal, served at /.well-known/openai-apps-challenge.Streamable HTTP MCP endpoint:
https://www.sheffieldmasjids.com/mcp
(/mcp rewrites to /api/mcp.) Tools:
| Tool | Purpose |
|---|---|
search_mosques | Find mosques by name, city, or country |
get_prayer_times | Adhan + iqamah for a mosque on YYYY-MM-DD (default: today Europe/London) |
Auth: none (public published times). Rate limit: 60 requests/minute/IP (same best-effort pattern as the HTTP API).
Plugin package for OpenAI directory submission lives in openai-plugin/ (plugin.json, mcp.json, skills/). Zip that folder when uploading to platform.openai.com/plugins.
bun run test:mcp
HTTP-only agents can resolve a slug from GET /data/mosques.json, then request:
GET /api/prayer-times?mosque=madina-masjid-sheffield&date=2026-04-10
date is optional and defaults to today in Europe/London. A 200 response has adhan and iqamah objects; iqamah is null on days whose published timetable has adhan times but no iqamah entry (adhan-only months), and is never filled in or calculated. A day with no published adhan row returns 404. The endpoint reads published static timetable files, never Convex, caches successful responses, and applies a best-effort per-instance limit of 60 requests per minute per client IP. Production should also enforce the same rule at the hosting firewall for a globally consistent limit.
External agents can report integration friction without a GitHub account. GET /api/feedback returns the machine-readable contract. Submit with POST /api/feedback (application/json or application/x-www-form-urlencoded, 8 KiB maximum). Clients that cannot POST can use the form at /report-api-issue, which shares the same validation and limits.
{
"schemaVersion": 1,
"category": "documentation",
"summary": "Agent could not discover the supported date format",
"request": { "method": "GET", "path": "/api/prayer-times", "query": { "mosque": "madina-masjid-sheffield", "date": "10/04/2026" } },
"response": { "status": 400, "contentType": "application/json", "bodyExcerpt": "Date must be a valid YYYY-MM-DD value." },
"expected": "Discover the YYYY-MM-DD format before making the request",
"actual": "The request used an unsupported date format",
"reproduction": ["Request /api/prayer-times with date=10/04/2026"],
"agent": { "name": "example-client", "version": "1.0" }
}
This is the beginning of the README. Read the rest at the original. Read the full README ↗