datetime-mcp-server
datetime MCP Server
現在の日付/時刻を照会する Model Context Protocol サーバーです。TypeScript で記述され、AWS Lambda 上にデプロイして Streamable HTTP で外部にサービスを提供する設計になっています。
機能特性
2つの 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 のフリーズ/解凍モデルに適合 |
| レスポンスが SSE ストリームではなく通常の JSON になり、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またはZに整形hourCycle: "h23":hour12: falseが一部の locale で"24"時の境界バグを生むのを回避DST と特殊タイムゾーン:offset はリクエスト時点で計算されるため、夏時間の切り替えは自然に正しく処理される(ニューヨーク
-04:00→-05:00)。30分/15分刻みのタイムゾーン(インド+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方法1: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 を出力。繰り返し実行しても安全で、自動的に更新パスを取ります。
方法2: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 タブで再アップロードするだけです。
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")のエイリアステーブルを引数ヒントに使用しておらず、エラーメッセージは3つの例のみ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