datetime-mcp-server
datetime MCP Server
一个提供当前日期/时间查询的 Model Context Protocol 服务器,采用 TypeScript 编写,设计为部署在 AWS Lambda 上,通过 Streamable HTTP 对外提供服务。
功能特性
两个 MCP 工具:
get_date、get_datetime,输出 ISO 8601 格式可选时区参数:支持 IANA 时区名(
Asia/Shanghai)和 UTC 偏移量(+08:00),默认 UTC零第三方时间库:完全基于 Node.js 内建
Intl(ICU),无 moment/luxon/dayjs 依赖Serverless 部署:单文件 bundle(约 2MB)+ Lambda Web Adapter,冷启动后热实例毫秒级响应
符合最新 MCP 标准:Streamable HTTP 传输、stateless 运行模式、协议版本协商由官方 SDK 处理
Related MCP server: date-today-mcp
架构
MCP Client ──HTTP POST /mcp──▶ Function URL ──▶ Lambda 函数
│
├─ LWA Layer (AWS_LAMBDA_EXEC_WRAPPER=/opt/bootstrap)
│ └─ 执行 zip 根目录 bootstrap → node dist/index.js
│
└─ Express app (端口 8080)
└─ POST /mcp → StreamableHTTPServerTransport
(stateless:每请求新建 transport,
enableJsonResponse 返回普通 JSON)关键机制:
组件 | 说明 |
Streamable HTTP | MCP 当前唯一推荐的 HTTP 传输;HTTP+SSE 已废弃 |
Stateless 模式 | 每个请求自包含、不维护会话,与 Lambda 的冻结/解冻模型契合 |
| 响应走普通 JSON 而非 SSE 流,避开 Lambda 响应缓冲限制 |
Lambda Web Adapter (LWA) | AWS 官方公共 Layer,把 Lambda invoke 翻译成对 localhost:8080 的真实 HTTP 请求 |
| LWA 接管后的真正进程入口( |
MCP 工具
get_date
返回当前日历日期,ISO 8601 YYYY-MM-DD。
参数 | 类型 | 必填 | 说明 |
| string | 否 | IANA 时区名或 UTC 偏移量,默认 |
{"result":{"content":[{"type":"text","text":"2026-08-24"}]}}get_datetime
返回当前日期时间,ISO 8601 带偏移量后缀(UTC 输出用 Z)。
{"result":{"content":[{"type":"text","text":"2026-08-23T14:30:00+08:00"}]}}错误行为
时区缺失或空白字符串 → 视为 UTC
非空但非法的时区 → 返回
isError: true结果,附提示信息:
Error: Invalid IANA timezone "Mars/Olympus". Use a name like "UTC", "Asia/Shanghai" or "America/New_York".协议层错误(如缺少 Accept 头)由 SDK 返回标准 JSON-RPC error
时间来源与精度
时间读取自运行环境的系统时钟(new Date())。本地即本机时钟(依赖 NTP 校准);在 Lambda 上宿主机时钟由 Amazon Time Sync Service(GPS/原子钟源,PTP/NTP)自动同步,误差毫秒级以内,无需任何配置。
刻意不做每次查询外部 NTP:AWS 时钟已持续同步,外查只会增加延迟(+10~100ms)、引入网络故障面和限流问题,准确度不会更高。
输出分辨率精确到秒(毫秒被截断)。时区转换是纯算术——所有时区拿到的是同一绝对瞬间,只是墙上时间表示不同。
本地开发
要求 Node.js ≥ 22。
npm install # 安装依赖
npm run dev # 构建 + 启动(默认 http://localhost:3000/mcp)
npm test # vitest 单测(14 个用例)
npm run typecheck # tsc --noEmit
npm run lint # eslint
npm run build # esbuild 打包为 CJS 单文件 dist/index.js本地手动测试(Accept 头必须同时声明两种媒体类型,这是 SDK 的协议校验):
curl -s http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_datetime","arguments":{"timezone":"Asia/Shanghai"}}}'也可使用官方调试器:npx @modelcontextprotocol/inspector,连接类型选 Streamable HTTP。
注意本机若设置了
http_proxy环境变量,curl 需加--noproxy '*',否则 localhost 请求会被代理拦截返回 502。
项目结构
├── src/
│ ├── time.ts # 核心纯函数:ISO 格式化、时区校验(可独立单测)
│ ├── server.ts # McpServer 实例 + 工具注册
│ └── index.ts # Express app + stateless transport 挂载 + 进程入口
├── test/
│ └── time.test.ts # 固定时间戳验证多时区/DST/半小时偏移/错误输入
├── build.mjs # esbuild 构建脚本(bundle: platform=node22, format=cjs)
├── bootstrap # LWA 进入口(zip 根目录,需可执行位 755)
├── deploy.sh # CLI 一键部署脚本
├── function.zip # 部署包(构建产物,不入库)
└── dist/index.js # 打包产物(约 2MB,零运行时依赖安装)技术实现要点
时区格式化全部通过 Intl.DateTimeFormat 完成,核心技巧:
日期:
en-CAlocale 天然输出YYYY-MM-DD,无需手工拼装带偏移量的时间:
formatToParts取目标时区的墙上时间各字段 → 用Date.UTC()把它当作 UTC 反算 → 与原始 instant 相减得到分钟级 offset → 格式化为±HH:MM或ZhourCycle: "h23":避免hour12: false在某些 locale 下产生"24"小时的边界 bugDST 与特殊时区:offset 按请求时刻计算,夏令时切换自然正确(纽约
-04:00→-05:00),半小时/刻钟时区(印度+05:30、尼泊尔+05:45、查塔姆+12:45)均被单测覆盖Formatter 缓存:按 timezone 缓存
Intl.DateTimeFormat实例,热实例上重复调用零构造开销时区校验:try/catch 构造
Intl.DateTimeFormat,非法值抛RangeError即视为无效。新版 ECMA-402 使 ICU 同时接受 UTC 偏移量字符串(如+08:00),已验证整条链路输出正确并纳入测试
部署到 AWS Lambda
前置条件:AWS CLI 已配置凭证;一个含 AWSLambdaBasicExecutionRole 权限的执行角色(没有可用下面命令创建):
aws iam create-role --role-name datetime-mcp-role \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
aws iam attach-role-policy --role-name datetime-mcp-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole方式一:CLI 脚本
ROLE_ARN=arn:aws:iam::<账号ID>:role/datetime-mcp-role ./deploy.sh可选环境变量:AWS_REGION(默认 us-east-1)、FUNCTION_NAME(默认 datetime-mcp)、ARCH(arm64/x86_64,默认 arm64)。
脚本流程:动态查询区域最新的 LWA Layer 版本 → esbuild 构建 → bsdtar 打包(系统无 zip 命令)→ create/update 函数(nodejs22.x、512MB、超时 10s)→ 创建无鉴权 Function URL 并授权公开调用 → 输出 endpoint。重复运行安全,自动走更新路径。
方式二:AWS 控制台
本地打包:
npm run build && bsdtar --format zip -cf function.zip bootstrap dist/index.jsLambda 控制台 → Create function → Author from scratch
Runtime:Node.js 22.x;Architecture:arm64
Permissions:Create a new role with basic Lambda permissions
Code 页签 → Upload from → .zip file → 选择
function.zip(内部结构必须是根目录bootstrap+dist/index.js)Layers 区 → Add a layer → AWS layers → LambdaAdapterLayerArm64(选最新版本)
Configuration → Environment variables:
Key
Value
AWS_LAMBDA_EXEC_WRAPPER/opt/bootstrapPORT8080Configuration → General configuration → Memory 512 MB、Timeout 10 s
Configuration → Function URL → Create → Auth type NONE
控制台创建 NONE 类型 Function URL 时会自动添加公开调用的资源策略,无需再执行
add-permission(这是与 CLI 的差异)。
浏览器直接访问 Function URL 返回 405 属正常(仅允许 POST)。以后更新代码:重新构建打包后在 Code 页签重新 Upload 即可。
MCP 客户端接入
以 opencode 为例,在配置中添加 remote MCP server:
{
"mcp": {
"datetime": {
"type": "remote",
"url": "https://<identifier>.lambda-url.<region>.on.aws/mcp"
}
}
}设计决策记录
决策 | 结论 | 理由 |
语言 | TypeScript |
|
传输模式 | Streamable HTTP + stateless + JSON response | Lambda 无持久进程,stdio 不可行;无会话状态天然匹配冻结/解冻模型;纯 JSON 避开 SSE 流式限制 |
SDK 版本 | 稳定版 | 正确实现协议版本协商,向后兼容旧客户端;2026-07-28 修订版的新特性(TTL 缓存等)对静态工具列表无意义;beta 拆分包 API 未稳定 |
时区实现 |
| 零依赖、Lambda 上无需补装 tzdata、精度足够 |
时间源 | 系统时钟而非每次查 NTP | AWS 已做亚毫秒同步;NTP 外查增加延迟/故障面/成本且无准确度收益 |
部署 | 手动 CLI/控制台 + LWA Layer | 不引入 SAM/CDK/Terraform 的前期投入;deploy.sh 仅是命令批处理,非 IaC |
故障排查
现象 | 原因与解决 |
| 请求缺 Accept 头。curl 测试需带 |
| 忘记挂 LWA Layer 或漏设 |
GET /mcp 返回 405 | 符合预期。stateless 模式不支持服务端推送流,仅接受 POST |
curl 本地测试返回 502 且响应极快 | 系统代理拦截了 localhost。加 |
Function URL 冷启动首个请求慢 | Lambda 冻结/解冻机制所致,后续请求毫秒级 |
打包时报 | 本机未装 zip 包(Arch 上与 unzip 是两个包)。本项目已改用 |
已知限制与未来改进
防御性 handler 未添加:若裸跑于默认 Node.js 运行时(无 LWA),报错信息晦涩。可导出一个提示性的占位 handler 改善误配置时的报错体验,对正常路径零影响
输出仅到秒级精度,未暴露毫秒
未做鉴权与限流——公开 endpoint 可能被滥用刷调用量(虽然单次成本趋近于零)
Intl.supportedValuesOf("timeZone")的别名表未用于参数提示,错误信息只给了三个示例SDK 未来从稳定版 1.x 迁移到拆分包(支持 2026-07-28 修订版)时需跟进 API 变更
License
This server cannot be deployed
Maintenance
Related MCP Connectors
Timezone MCP — wraps timeapi.io (free, no auth)
A real clock for AI agents: current time, timezone conversion, and DST facts from the IANA tzdb.
Current time in any IANA time zone, plus the full time-zone list. Via timeapi.io.
Related MCP Servers
- FlicenseAqualityNot gradedmaintenanceProvides timezone-aware date and time information with configurable time formats and timezone support. Enables users to get current date and time in their preferred timezone and format through simple MCP tools.2-
- AlicenseAqualityDmaintenanceProvides the current date in multiple formats (e.g., European, ISO, US) via a simple MCP tool.1ISC
- AlicenseAqualityDmaintenanceA simple MCP server that returns the current date and time with timezone information in ISO 8601, Unix timestamp, and human-readable formats.1MIT
- AlicenseNot gradedqualityDmaintenanceProvides time-related tools including current time retrieval, timezone conversion, time formatting, and timezone info via MCP.7 npmMIT