time-mcp
by kitallis
README.md
# time-mcp
A remote MCP server that gives Claude **ambient time awareness**: current time,
timezone conversion, calendar math, and elapsed-time — with tool descriptions
written so the model treats time as context it must *acquire* (calling the tool
before time-sensitive reasoning), not just something to answer "what time is it?".
Inspired by [yokingma/time-mcp](https://github.com/yokingma/time-mcp), rebuilt
as a stateless Streamable-HTTP server so it works as a **claude.ai custom
connector** (which requires a public HTTPS URL, not stdio).
## Tools
| Tool | Purpose |
|------|---------|
| `current_time` | Full temporal context: ISO time, date, weekday, ISO week, unix, offset, DST |
| `convert_time` | Convert a date-time between IANA timezones |
| `time_math` | Add/subtract years/months/weeks/days/hours/minutes (DST- and calendar-safe) |
| `time_difference` | Exact elapsed time between two instants (end defaults to now) |
| `days_in_month` | Days in a month, leap-year aware |
## Deploy
```sh
npm install
npx wrangler deploy
```
Requires a Cloudflare account (`npx wrangler login` first). Free tier is plenty.
## Connect
In claude.ai: **Settings → Connectors → Add custom connector**, URL:
```
https://time-mcp.<your-subdomain>.workers.dev/mcp?tz=Asia/Kolkata
```
The `?tz=` query param sets the default timezone for all tools (falls back to
`DEFAULT_TIMEZONE` in `wrangler.jsonc`, then UTC). Claude Code / Desktop can use
the same URL: `claude mcp add --transport http time <url>`.
To make usage closer to "every response" (best-effort — chat has no true
pre-response hook), add this under **Settings → General → Instructions for
Claude** in claude.ai:
```
Treat time as ambient context you must acquire, not knowledge you have. Call the time connector's current_time at the start of every response, regardless of topic, before reasoning about anything. Never state or assume a date, day of week, elapsed time, or how recent something is without having called it in this turn.
```
Also check the per-chat tools menu: connectors have an enable toggle, and
nothing fires in a chat where the connector is toggled off.
## Testing the invocation rate
The failure mode to test for is not "can it tell the time" but "does it reach
for the clock when time matters only *implicitly*". Run each prompt in a
**fresh chat** (within one chat the model legitimately reuses an earlier
result), then expand the tool-call chips in the response to see what it called:
1. "What day of the week is it?" — sanity check; must call `current_time`.
2. "How old is the M3 MacBook Pro?" — age/recency with no time words.
3. "Draft a message proposing a call next Tuesday 3pm my time to someone in
New York." — relative date + timezone; expect `current_time`, ideally
`convert_time` too.
4. "My notice period is 45 days and I want to be done by end of September —
when's my last day to resign?" — deadline arithmetic; expect `time_math`,
not mental math.
5. "Is it too late to file taxes?" — pure implicit deadline.
6. Negative control: "Explain how Raft leader election works." — calling here
is harmless but unnecessary; over-firing means the instructions are heavier
than needed.
For ground truth independent of the UI, watch the server while testing:
```sh
npx wrangler tail time-mcp
```
If the hit rate is poor, the two levers in order of strength are the
Instructions text above and the tool descriptions in `src/tools.ts`
(the model re-reads tool descriptions every turn).
## Local dev
```sh
npm run dev # wrangler dev on :8787
npm run check # typecheck
```
Smoke test:
```sh
curl -s localhost:8787/mcp -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"current_time","arguments":{}}}'
```
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues