The Hyper-Local Agent: Unpacking waktu-solat-mcp
How a minimalist Python protocol server uses modern tooling to inject culturally specific, astronomically derived scheduling into Claude and Cursor.
- waktu-solat-mcp gives general LLMs hyper-specific, localized context by connecting them to official Malaysian prayer time data using the Model Context Protocol.
- The server abstracts complex timezone logic, ensuring that 'today' remains consistent with Malaysian time regardless of where the MCP server is hosted.
- Built on modern Python tooling like uv and FastMCP, it provides a lightweight, easily deployable dual-transport architecture for both local and cloud use.
The Geographic Blindness of Global Models
Large Language Models possess an immense breadth of knowledge, but they are inherently generalized and geographically blind. While an LLM understands the concept of Islamic prayer times and the astronomical principles behind them, it lacks the hyper-local precision required for daily observance. In Malaysia, prayer times are not merely mathematical estimates; they are strictly defined and verified by the local religious authority, JAKIM. A global model cannot reliably calculate these verified times on the fly.
This limitation is where waktu-solat-mcp enters the picture. It acts as a necessary bridge, giving global agents like Claude a very specific sense of time and place. By providing a programmatic interface to the official JAKIM data via the Model Context Protocol (MCP), it ensures that when a user in Kuala Lumpur asks their AI assistant for the next prayer time, they receive an accurate, verified answer rather than a generic hallucination.
Malaysia Prayer Time MCP Server provides accurate Islamic prayer times for locations throughout Malaysia. This server implements the Model Context Protocol (MCP) to seamlessly integrate with Claude Desktop, delivering real-time prayer schedules directly through your AI assistant.
Translating Tradition into Context
The core responsibility of the MCP server resides in src/waktusolat_mcp/server.py. This translation layer is defined by a set of specific tools exposed to the LLM, such as get_prayer_times_today and get_next_prayer. The server fetches raw JSON data from the api.waktusolat.app endpoint, but it does not simply pass this raw data back to the model.
Instead, it parses the data into structured, human-readable strings. This is a critical design choice: forcing the LLM to interpret complex JSON structures and perform time math increases the risk of errors. By calculating the remaining time internally (e.g., "Maghrib is in 2h 15m") and returning a clear string, the server guarantees accuracy. Furthermore, the WaktuSolatAPI class implements an in-memory cache to prevent redundant network calls when the LLM asks follow-up questions, improving responsiveness.
Anchoring Time in a Floating World
Timezone management is notoriously complex, especially when dealing with data tied to specific geographic locations while the server itself might be hosted anywhere in the world. The codebase addresses this by explicitly defining the Malaysian timezone: MYT = timezone(timedelta(hours=8)).
This explicit declaration is vital. If the MCP server is deployed on a cloud provider like Railway, whose default servers operate in UTC, relying on the system's local time would cause the definition of "today" to shift incorrectly. By anchoring all datetime conversions to Asia/Kuala_Lumpur, the server ensures constant synchronization with the user's reality.
The FastMCP and uv Advantage
The underlying infrastructure of waktu-solat-mcp reflects a highly modern approach to Python development. It leverages FastMCP, an SDK that abstracts away the boilerplate of the Model Context Protocol, allowing the developer to focus purely on defining the tools and logic.
Complementing this is the use of Astral's uv package manager. Specified in the pyproject.toml, uv handles dependency resolution with remarkable speed. This combination results in a clean, maintainable codebase and a highly optimized Docker build process, reducing the friction typically associated with setting up and deploying Python environments.
Escaping Localhost
While many MCP servers are designed exclusively for local execution via standard I/O (stdio), waktu-solat-mcp is built with dual-transport versatility. It includes configurations for both local CLI use and a public HTTP endpoint.
This cloud-native capability, enabled by a multi-stage Dockerfile and a Procfile, allows users to deploy the server to services like Railway or Render. This means Claude Desktop can access the data via a URL, untethering the functionality from the developer's local machine and making it accessible across different environments.
| Protocol | Primary Use Case | Host Environment | Setup Friction |
|---|---|---|---|
| stdio | Local IDEs (Cursor) | Developer's laptop | Zero-config local |
| HTTP/SSE | Claude Desktop / Hosted Agents | Railway/Render | Requires URL configuration |