Skip to main content
Glama
ploutonconsulting

date-mcp

README.md
# date-mcp

[![CI](https://github.com/ploutonconsulting/date-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/ploutonconsulting/date-mcp/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)

An **[MCP](https://modelcontextprotocol.io) server** that gives AI agents accurate
date, time, timezone, and interval information.

Large language models are notoriously unreliable at knowing what "now" is,
computing durations, and reasoning across timezones — they guess, and they guess
wrong. `date-mcp` closes that gap by exposing deterministic, system-clock-backed
tools an agent can call for the truth instead of hallucinating it.

## Design principles

- **Correctness first.** Every value is derived from the real system clock and the
  IANA timezone database — never from a model's sense of time.
- **No ambiguity.** All timestamps are ISO-8601 / RFC-3339 with an explicit UTC
  offset. Nothing naive ever leaves the server.
- **Self-describing results.** Tools return the ISO string *and* broken-out
  calendar fields, so consumers don't have to re-parse.

## Requirements

- Python 3.10+

## Installation

```bash
pip install date-mcp
```

Or, from source:

```bash
git clone https://github.com/ploutonconsulting/date-mcp.git
cd date-mcp
pip install -e ".[dev]"
```

## Usage

Run the server over stdio:

```bash
date-mcp
# or
python -m date_mcp
```

### Configure in an MCP client

For a client that reads a JSON config (e.g. Claude Desktop), add:

```json
{
  "mcpServers": {
    "date-mcp": {
      "command": "date-mcp"
    }
  }
}
```

## Tools

| Tool | Description |
| ---- | ----------- |
| `get_current_time(timezone="UTC")` | Current date/time for an IANA timezone, as ISO-8601 with offset plus broken-out calendar fields. |
| `get_weekday_date(weekday, week_start=None, timezone=None)` | The date of a named weekday within the current week. |
| `validate_weekday_date(weekday, claimed_date, week_start=None, timezone=None)` | Validate a weekday+date claim against the current week and correct it if wrong. |

> The tool surface is expanding as requirements are agreed (timezone conversion,
> duration/interval maths, business-day calculations, parsing). See
> [`CHANGELOG.md`](CHANGELOG.md) and open a [feature request](https://github.com/ploutonconsulting/date-mcp/issues/new/choose).

### Example

```python
get_current_time(timezone="Europe/London")
# {
#   "iso8601": "2026-07-10T14:32:05.123456+01:00",
#   "timezone": "Europe/London",
#   "utc_offset": "+0100",
#   "unix": 1783434725.123456,
#   "year": 2026, "month": 7, "day": 10,
#   "hour": 14, "minute": 32, "second": 5, "microsecond": 123456,
#   "weekday": "Friday", "iso_weekday": 5, "day_of_year": 191
# }
```

### `get_weekday_date` and `validate_weekday_date`

These answer "what date is this Wednesday?" and "is Friday actually the 11th?"
deterministically — "this week" is anchored to today in `timezone` and bounded by
`week_start`, never guessed by the model.

Both tools take:

- `weekday` — full name or 3-letter abbreviation (e.g. `"Wednesday"`, `"wed"`),
  case-insensitive.
- `week_start` — day the week starts on (name or abbreviation). Optional.
- `timezone` — IANA timezone name anchoring "today". Optional.

`validate_weekday_date` additionally takes `claimed_date` — the caller's asserted
date, ISO `YYYY-MM-DD`.

Every optional parameter resolves through the same precedence chain:

1. the value passed to the tool call,
2. `config.ini` (see [Configuration](#configuration)),
3. for `timezone` only, the detected OS timezone,
4. the built-in default — `"UTC"` for `timezone`, `"Monday"` for `week_start`.

`weekday_format` (`"full"` or `"abbreviated"`) is not a tool parameter — it is
config-only and applies to the weekday names in every response.

`get_weekday_date` returns the target date's calendar fields (`iso_date`,
`iso_weekday`, `year`, `month`, `day`, `day_of_year`), the formatted `weekday`
name, the week's `week_start`/`week_start_date`/`week_end_date`, and the echoed
`timezone` and `reference_date`.

`validate_weekday_date` returns `is_correct`, the `weekday` name, the
`claimed_date`/`claimed_weekday` (the actual weekday of `claimed_date`, useful as
a diagnostic when the claim is wrong), the `corrected_date`/`corrected_weekday`,
the week's `week_start`/`week_start_date`/`week_end_date`, and the echoed
`timezone` and `reference_date`.

#### Example

If today is Friday 10 July 2026 and an agent claims "Friday 11 July 2026":

```python
validate_weekday_date(weekday="Friday", claimed_date="2026-07-11")
# {
#   "is_correct": false,
#   "weekday": "Friday",
#   "claimed_date": "2026-07-11",
#   "claimed_weekday": "Saturday",
#   "corrected_date": "2026-07-10",
#   "corrected_weekday": "Friday",
#   "week_start": "Monday",
#   "week_start_date": "2026-07-06",
#   "week_end_date": "2026-07-12",
#   "timezone": "UTC",
#   "reference_date": "2026-07-10"
# }
```

`claimed_date` (11th) is a Saturday, not a Friday, so the claim is corrected to
the 10th — the actual Friday in the current week.

## Configuration

date-mcp reads an optional `config.ini` to set defaults for `timezone`,
`week_start`, and `weekday_format`. Every setting is optional; anything omitted
falls back to a built-in default.

**Discovery order** (first existing file wins):

1. the path in the `DATE_MCP_CONFIG` environment variable,
2. `~/.config/date-mcp/config.ini`,
3. `./config.ini` (the server's working directory).

**Settings:**

| Section | Key | Description | Default |
| ------- | --- | ----------- | ------- |
| `[defaults]` | `timezone` | IANA timezone used when a tool call omits `timezone`. | detected OS zone, else `UTC` |
| `[defaults]` | `week_start` | Day the week starts on (full name or 3-letter abbreviation). | `Monday` |
| `[output]` | `weekday_format` | Weekday-name rendering: `full` (`Wednesday`) or `abbreviated` (`Wed`). | `full` |

When `timezone` is omitted from both the tool call and `config.ini`, date-mcp
detects the machine's local IANA zone via [`tzlocal`](https://pypi.org/project/tzlocal/)
and falls back to `UTC` only if that detection fails.

A malformed config file or an invalid setting (unknown timezone, unrecognised
`week_start`, or bad `weekday_format`) raises when the server starts
(fail-fast) rather than silently falling back.

See [`config.example.ini`](config.example.ini) for a commented sample.

## Development

```bash
pip install -e ".[dev]"
pre-commit install
ruff check . && ruff format --check .
mypy
pytest
```

## Contributing

Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) and our
[Code of Conduct](CODE_OF_CONDUCT.md). To report a vulnerability, see
[SECURITY.md](SECURITY.md).

## License

[MIT](LICENSE) © Pierre Oosthuizen

TDQS

A4.5/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: get_current_time returns current datetime, get_weekday_date resolves a weekday to a date, and validate_weekday_date checks/corrects a claimed date. No overlap in functionality.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern (get_current_time, get_weekday_date, validate_weekday_date) with identical casing and style.

Tool Count5/5

Three tools is well-scoped for a date utility server. Each tool serves a distinct and useful purpose without being too few or too many.

Completeness4/5

The set covers core date operations (current time, weekday resolution, validation) but is missing common utilities like date arithmetic, format conversion, or date difference. Minor gap.

Maintenance

ActivityInactive
ResponsivenessNo issues