Skip to main content
Glama
date-mcp

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 recent community issues