at-mcp
at-mcp is a small MCP server that lets an agent run duration timers and check the current time, so it can track whether a user-requested minimum task duration has elapsed.
Start a timer (
start_timer) — givenmin_seconds(a positive whole number of seconds, rounded up from the requested duration, e.g. 30 minutes = 1800), creates an independent timer and returns its UUID, original minimum, elapsed, remaining, and whether the minimum is met.Check a timer (
check_timer) — read a timer's status without modifying it; intended after long tool calls, at phase changes, and immediately before a completion response.Handle revised minimums —
minimum_metalways reflects the originalmin_seconds; if the user changes the requirement, compareelapsed_secondsagainst the revised duration rounded up, reusing the same timer.Reuse timers per task — each
start_timercall creates a new timer rather than resetting one, so the sametimer_idshould be kept in task context and reused across status checks and context compaction.Check the current time (
get_current_time, per the README) — returns the system time with its UTC offset and resolved time zone, with an optionaltime_zonesuch asAsia/SeoulorUTC, for interpreting deadlines like "work until 9 PM."Know the limits — timers use a monotonic clock (unaffected by system time changes), live only in process memory until the server exits (no persistence, reset, expiration, or waiting tool), and invalid inputs or unknown timer IDs return errors rather than a satisfied minimum.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@at-mcpwork on this for at least 30 minutes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
at-mcp
A local MCP server that helps agents stay aware of elapsed time and check whether a user-requested minimum task duration has been met. For a request such as “work for at least 30 minutes,” the agent starts a 1,800-second timer and checks it before its final response.
The server measures elapsed time, including tool waits. It does not measure active effort, judge task completion, or block an agent from ending early. Compliance depends on the agent following the instructions.
Setup
Requires Node.js 24.12.0 or newer and npm.
npx --yes at-mcp@latestThe server listens on stdin and writes MCP messages to stdout. It exits when the client closes stdin. It is normally launched by your MCP host rather than used interactively.
Related MCP server: Time & Millisecond Converter MCP Server
Connect
Add the following entry to your MCP host's configuration, adapting the surrounding structure to that host:
{
"mcpServers": {
"at-mcp": {
"command": "npx",
"args": ["--yes", "at-mcp@latest"]
}
}
}Codex
codex mcp add at-mcp -- npx --yes at-mcp@latestOr add this to ~/.codex/config.toml (Codex MCP docs):
[mcp_servers.at-mcp]
command = "npx"
args = ["--yes", "at-mcp@latest"]Tools
Tool | Input | Behavior |
|
| Creates an independent timer and returns its UUID and status. |
|
| Returns the current status without modifying the timer. |
| Optional | Returns the current system time with its UTC offset and resolved time zone. Defaults to the server's local time zone. |
For a request such as “work until 9 PM,” call get_current_time with the user's time zone and interpret the deadline using the returned date and local time. Preserve that deadline in task context and check the time before reporting completion. If the date or time zone is unclear, ask the user rather than assuming the server's default matches their location.
With {"time_zone":"Asia/Seoul"}, get_current_time returns the following as structured content and JSON text:
{
"current_time": "2026-10-01T21:00:00.123+09:00",
"time_zone": "Asia/Seoul"
}Time-zone offsets reflect daylight saving time. If the server's local zone has no usable name, time_zone contains its current UTC offset instead. This tool uses the system clock; minimum-duration checks use the monotonic timers.
The timer tools return the same status as structured content and JSON text:
{
"timer_id": "e39dadf5-6cd0-40ab-88df-cbb2fb1b27dc",
"min_seconds": 1800,
"elapsed_seconds": 1240,
"remaining_seconds": 560,
"minimum_met": false
}Elapsed seconds are rounded down, and remaining seconds are rounded up to a minimum of zero. minimum_met compares the unrounded elapsed duration with the requested minimum, so it cannot become true early because of rounding. Timing uses Node.js's monotonic process.hrtime.bigint() and is unaffected by system time adjustments. Timer ID lookups are case-insensitive and return the canonical lowercase ID.
Each start call creates a new timer; it does not reset an existing one. Timers stay in process memory until the server exits, including after their minimum duration has elapsed. There is no automatic expiration, persistence, reset, or waiting tool. A server restart loses all timers. Invalid inputs and unknown IDs return isError: true; missing timers are never treated as having met their minimum.
Development
Install pnpm and work from the repository checkout:
pnpm install --frozen-lockfile
pnpm check
pnpm test
pnpm startDevelopment runs TypeScript directly in Node.js. pnpm build replaces dist/ with the compiled JavaScript CLI so old build artifacts cannot enter a release. To connect a host to your checkout, use node as the command and the absolute path to src/index.ts as its argument.
Publishing
Log in once with npm login, then publish:
npm publish --access publicPublishing runs type checks, tests, and the build automatically, then installs a temporary package and verifies its CLI and all MCP tools. Run pnpm check:package to perform the package check separately. npm reads the version from package.json. For subsequent releases, bump it with npm version patch --no-git-tag-version, using minor or major as appropriate.
Available Tools
2 toolscheck_timerARead-onlyIdempotent
Check the saved timer after long tool calls, at phase changes, and immediately before a completion response. Require both the current minimum duration and task completion. minimum_met refers to the original min_seconds; if the user revises the minimum, compare elapsed_seconds with the revised duration rounded up to whole seconds, using the same timer. Continue useful work within task scope until both conditions are met; avoid idle waiting, rapid polling, redundant tests, and unrelated changes. Progress updates are allowed. Honor explicit stop requests immediately. Errors do not establish elapsed time; recover if possible or report the limitation without claiming completion.
| Name | Required | Description | Default |
|---|---|---|---|
| timer_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| timer_id | Yes | |
| min_seconds | Yes | |
| minimum_met | Yes | |
| elapsed_seconds | Yes | |
| remaining_seconds | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the operation as read-only, idempotent, and non-destructive. The description adds substantial context beyond them: how minimum_met relates to the original min_seconds, how revised minima are compared, that errors do not establish elapsed time, and that explicit stop requests must be honored immediately. This is rich, non-obvious behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a long unbroken paragraph. While most sentences carry behavioral rules, some are repetitive (both conditions are stated more than once), and there is no formatting or grouping to help scanning. Adequate but not tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values are covered. The description thoroughly explains the timing logic and error behavior, but omits how to obtain the timer_id and the relationship to start_timer, leaving an agent to infer it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the single required parameter timer_id has no description in the schema. The tool description never explains what timer_id is, where it comes from (presumably start_timer), or its format, so it fails to compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Check the saved timer...' which is a specific verb and resource, and clarifies the two conditions (minimum duration and task completion) that the check evaluates. It does not explicitly differentiate from the sibling start_timer, so 4 rather than 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to call: after long tool calls, at phase changes, and immediately before a completion response. It also gives behavioral constraints (avoid idle waiting, rapid polling, redundant tests) but never names alternative tools or a when-not-to-use case, so 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_timerA
Start a timer at the beginning of a task with a user-requested minimum duration. Convert the duration to whole seconds, rounding up (30 minutes = 1800). Preserve timer_id and min_seconds in task context and summaries. Each call creates a new timer; reuse the existing timer for the same task, including after status questions and context compaction.
| Name | Required | Description | Default |
|---|---|---|---|
| min_seconds | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| timer_id | Yes | |
| min_seconds | Yes | |
| minimum_met | Yes | |
| elapsed_seconds | Yes | |
| remaining_seconds | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false and destructiveHint=false, and the description reinforces this by warning that every call creates a new timer. It adds genuinely new context beyond the annotations by specifying the rounding-up conversion and the requirement to preserve timer_id and min_seconds in task context and summaries.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the core action followed by the conversion rule and the deduplication/state rule. No filler, and each sentence carries a distinct instruction.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the description covers the remaining gaps: unit conversion, the non-idempotent create-a-new-timer behavior, and what state to carry forward. Nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the sole parameter min_seconds is only constrained by type, exclusiveMinimum 0 and a maximum. The description fully compensates by defining the unit (whole seconds), the rounding rule (round up) and a worked example (30 minutes = 1800).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a concrete verb+resource ('Start a timer') and qualifies the scope as the beginning of a task with a user-requested minimum duration, so an agent can immediately tell it apart from check_timer by the verb alone. It stops short of naming the sibling explicitly, which keeps it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to call (at the start of a task) and, unusually, a when-not rule: 'Each call creates a new timer; reuse the existing timer for the same task, including after status questions and context compaction.' The alternative tool check_timer is never named, so the routing guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.2- First observed
check_timer - First observed
start_timer
TDQS
Scored across 2 tools
start_timer and check_timer have clearly distinct actions: one creates a timer, the other inspects an existing timer. The descriptions reinforce this separation, leaving no ambiguity about which tool to use.
Both tool names follow a consistent snake_case verb_noun pattern: start_timer and check_timer. This predictable convention makes the set easy to scan and use.
Two tools is borderline thin for a timer-related server, as there is no explicit stop, reset, pause, or list operation. The pair is coherent, but the surface feels minimal for the apparent domain.
The set covers starting and checking a timer but lacks an explicit stop/delete/reset tool, which is a notable lifecycle gap. The description mentions honoring stop requests, but there is no dedicated tool to perform that operation.
Maintenance
Related MCP Connectors
Wall-clock awareness for LLM agents. Two tools: elapsed-time-between-turns + day rollover detection.
Agent utility belt: memory, locks, webhook inboxes, timers, DNS, email, URL, timezone, cron
Concierge MCP for agentic workflows: verified time + drift, uuid, diff, calc, attest, verify.
Time and date math for AI agents: Unix timestamp conversion, DST-correct time zone conversion, durations, epoch arithmetic, cron schedules, and holiday countdowns. Eight tools, no key.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides LLM agents with a sense of time between turns via two MCP tools that track elapsed time and day rollover per conversation thread.19 PyPI3MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to accurately parse, format, and convert time durations and millisecond values with deterministic precision, avoiding common arithmetic errors.6 npm3-
- AlicenseNot gradedqualityCmaintenanceEnables coding agents to create, start, pause, and delete labeled timers within projects, with persistence via SQLite, through a stdio MCP interface.MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI models to answer time-related questions by providing tools for current time and elapsed time.-