mcp-time-context 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
5
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
6
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
7
+ // Store the timestamp of the last message
8
+ let lastMessageTime = null;
9
+ // Helper: get human friendly time gap description
10
+ function describeTimeGap(lastTime, now) {
11
+ const diffMs = now.getTime() - lastTime.getTime();
12
+ const diffMins = Math.floor(diffMs / 60000);
13
+ const diffHours = Math.floor(diffMins / 60);
14
+ const diffDays = Math.floor(diffHours / 24);
15
+ if (diffMins < 2)
16
+ return "just now (continuing the same conversation)";
17
+ if (diffMins < 60)
18
+ return `${diffMins} minutes ago (same session)`;
19
+ if (diffHours < 24)
20
+ return `${diffHours} hour(s) ago — treat this as a returning user, not a continuous conversation`;
21
+ if (diffDays === 1)
22
+ return `about 1 day ago — this is a next-day continuation, reset conversational tone accordingly`;
23
+ return `${diffDays} days ago — user is returning after a significant gap, treat this as a fresh start with prior context`;
24
+ }
25
+ // Create the MCP server
26
+ const server = new index_js_1.Server({
27
+ name: "mcp-time-context",
28
+ version: "1.0.0",
29
+ }, {
30
+ capabilities: {
31
+ tools: {},
32
+ },
33
+ });
34
+ // List available tools
35
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
36
+ return {
37
+ tools: [
38
+ {
39
+ name: "get_time_context",
40
+ description: "Returns the current date, time, timezone, and how long it has been since the user last sent a message. Use this at the start of every conversation turn to understand temporal context.",
41
+ inputSchema: {
42
+ type: "object",
43
+ properties: {},
44
+ required: [],
45
+ },
46
+ },
47
+ ],
48
+ };
49
+ });
50
+ // Handle tool calls
51
+ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
52
+ if (request.params.name === "get_time_context") {
53
+ const now = new Date();
54
+ // Build time gap context
55
+ let gapContext = "This is the first message in this session.";
56
+ if (lastMessageTime) {
57
+ gapContext = `User's last message was ${describeTimeGap(lastMessageTime, now)}`;
58
+ }
59
+ // Update last message time
60
+ lastMessageTime = now;
61
+ const context = {
62
+ current_date: now.toLocaleDateString("en-US", {
63
+ weekday: "long",
64
+ year: "numeric",
65
+ month: "long",
66
+ day: "numeric",
67
+ }),
68
+ current_time: now.toLocaleTimeString("en-US", {
69
+ hour: "2-digit",
70
+ minute: "2-digit",
71
+ timeZoneName: "short",
72
+ }),
73
+ iso_timestamp: now.toISOString(),
74
+ unix_timestamp: Math.floor(now.getTime() / 1000),
75
+ conversation_gap: gapContext,
76
+ instruction: "Use this temporal context to respond naturally. If the user is returning after hours or days, acknowledge the time gap subtly and don't assume conversation continuity.",
77
+ };
78
+ return {
79
+ content: [
80
+ {
81
+ type: "text",
82
+ text: JSON.stringify(context, null, 2),
83
+ },
84
+ ],
85
+ };
86
+ }
87
+ throw new Error(`Unknown tool: ${request.params.name}`);
88
+ });
89
+ // Start the server
90
+ async function main() {
91
+ const transport = new stdio_js_1.StdioServerTransport();
92
+ await server.connect(transport);
93
+ console.error("mcp-time-context server running...");
94
+ }
95
+ main().catch((error) => {
96
+ console.error("Fatal error:", error);
97
+ process.exit(1);
98
+ });
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "mcp-time-context",
3
+ "version": "1.0.0",
4
+ "description": "An MCP server that gives LLMs awareness of current time and conversation time gaps",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "mcp-time-context": "dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "start": "node dist/index.js",
12
+ "dev": "ts-node src/index.ts"
13
+ },
14
+ "keywords": [
15
+ "mcp",
16
+ "time",
17
+ "context",
18
+ "llm",
19
+ "claude",
20
+ "temporal"
21
+ ],
22
+ "author": "puneethass",
23
+ "license": "MIT",
24
+ "dependencies": {
25
+ "@modelcontextprotocol/sdk": "^1.27.1",
26
+ "zod": "^3.22.4"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^25.5.0",
30
+ "ts-node": "^10.9.2",
31
+ "typescript": "^5.9.3"
32
+ }
33
+ }
package/src/index.js ADDED
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
+ return new (P || (P = Promise))(function (resolve, reject) {
6
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
10
+ });
11
+ };
12
+ var __generator = (this && this.__generator) || function (thisArg, body) {
13
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
14
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
15
+ function verb(n) { return function (v) { return step([n, v]); }; }
16
+ function step(op) {
17
+ if (f) throw new TypeError("Generator is already executing.");
18
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
19
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
20
+ if (y = 0, t) op = [op[0] & 2, t.value];
21
+ switch (op[0]) {
22
+ case 0: case 1: t = op; break;
23
+ case 4: _.label++; return { value: op[1], done: false };
24
+ case 5: _.label++; y = op[1]; op = [0]; continue;
25
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
26
+ default:
27
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
28
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
29
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
30
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
31
+ if (t[2]) _.ops.pop();
32
+ _.trys.pop(); continue;
33
+ }
34
+ op = body.call(thisArg, _);
35
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
36
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
37
+ }
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ var index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
41
+ var stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
42
+ var types_js_1 = require("@modelcontextprotocol/sdk/types.js");
43
+ // Store the timestamp of the last message
44
+ var lastMessageTime = null;
45
+ // Helper: get human friendly time gap description
46
+ function describeTimeGap(lastTime, now) {
47
+ var diffMs = now.getTime() - lastTime.getTime();
48
+ var diffMins = Math.floor(diffMs / 60000);
49
+ var diffHours = Math.floor(diffMins / 60);
50
+ var diffDays = Math.floor(diffHours / 24);
51
+ if (diffMins < 2)
52
+ return "just now (continuing the same conversation)";
53
+ if (diffMins < 60)
54
+ return "".concat(diffMins, " minutes ago (same session)");
55
+ if (diffHours < 24)
56
+ return "".concat(diffHours, " hour(s) ago \u2014 treat this as a returning user, not a continuous conversation");
57
+ if (diffDays === 1)
58
+ return "about 1 day ago \u2014 this is a next-day continuation, reset conversational tone accordingly";
59
+ return "".concat(diffDays, " days ago \u2014 user is returning after a significant gap, treat this as a fresh start with prior context");
60
+ }
61
+ // Create the MCP server
62
+ var server = new index_js_1.Server({
63
+ name: "mcp-time-context",
64
+ version: "1.0.0",
65
+ }, {
66
+ capabilities: {
67
+ tools: {},
68
+ },
69
+ });
70
+ // List available tools
71
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, function () { return __awaiter(void 0, void 0, void 0, function () {
72
+ return __generator(this, function (_a) {
73
+ return [2 /*return*/, {
74
+ tools: [
75
+ {
76
+ name: "get_time_context",
77
+ description: "Returns the current date, time, timezone, and how long it has been since the user last sent a message. Use this at the start of every conversation turn to understand temporal context.",
78
+ inputSchema: {
79
+ type: "object",
80
+ properties: {},
81
+ required: [],
82
+ },
83
+ },
84
+ ],
85
+ }];
86
+ });
87
+ }); });
88
+ // Handle tool calls
89
+ server.setRequestHandler(types_js_1.CallToolRequestSchema, function (request) { return __awaiter(void 0, void 0, void 0, function () {
90
+ var now, gapContext, context;
91
+ return __generator(this, function (_a) {
92
+ if (request.params.name === "get_time_context") {
93
+ now = new Date();
94
+ gapContext = "This is the first message in this session.";
95
+ if (lastMessageTime) {
96
+ gapContext = "User's last message was ".concat(describeTimeGap(lastMessageTime, now));
97
+ }
98
+ // Update last message time
99
+ lastMessageTime = now;
100
+ context = {
101
+ current_date: now.toLocaleDateString("en-US", {
102
+ weekday: "long",
103
+ year: "numeric",
104
+ month: "long",
105
+ day: "numeric",
106
+ }),
107
+ current_time: now.toLocaleTimeString("en-US", {
108
+ hour: "2-digit",
109
+ minute: "2-digit",
110
+ timeZoneName: "short",
111
+ }),
112
+ iso_timestamp: now.toISOString(),
113
+ unix_timestamp: Math.floor(now.getTime() / 1000),
114
+ conversation_gap: gapContext,
115
+ instruction: "Use this temporal context to respond naturally. If the user is returning after hours or days, acknowledge the time gap subtly and don't assume conversation continuity.",
116
+ };
117
+ return [2 /*return*/, {
118
+ content: [
119
+ {
120
+ type: "text",
121
+ text: JSON.stringify(context, null, 2),
122
+ },
123
+ ],
124
+ }];
125
+ }
126
+ throw new Error("Unknown tool: ".concat(request.params.name));
127
+ });
128
+ }); });
129
+ // Start the server
130
+ function main() {
131
+ return __awaiter(this, void 0, void 0, function () {
132
+ var transport;
133
+ return __generator(this, function (_a) {
134
+ switch (_a.label) {
135
+ case 0:
136
+ transport = new stdio_js_1.StdioServerTransport();
137
+ return [4 /*yield*/, server.connect(transport)];
138
+ case 1:
139
+ _a.sent();
140
+ console.error("mcp-time-context server running...");
141
+ return [2 /*return*/];
142
+ }
143
+ });
144
+ });
145
+ }
146
+ main().catch(function (error) {
147
+ console.error("Fatal error:", error);
148
+ process.exit(1);
149
+ });
package/src/index.ts ADDED
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import {
6
+ CallToolRequestSchema,
7
+ ListToolsRequestSchema,
8
+ } from "@modelcontextprotocol/sdk/types.js";
9
+ import { z } from "zod";
10
+
11
+ // Store the timestamp of the last message
12
+ let lastMessageTime: Date | null = null;
13
+
14
+ // Helper: get human friendly time gap description
15
+ function describeTimeGap(lastTime: Date, now: Date): string {
16
+ const diffMs = now.getTime() - lastTime.getTime();
17
+ const diffMins = Math.floor(diffMs / 60000);
18
+ const diffHours = Math.floor(diffMins / 60);
19
+ const diffDays = Math.floor(diffHours / 24);
20
+
21
+ if (diffMins < 2) return "just now (continuing the same conversation)";
22
+ if (diffMins < 60) return `${diffMins} minutes ago (same session)`;
23
+ if (diffHours < 24) return `${diffHours} hour(s) ago — treat this as a returning user, not a continuous conversation`;
24
+ if (diffDays === 1) return `about 1 day ago — this is a next-day continuation, reset conversational tone accordingly`;
25
+ return `${diffDays} days ago — user is returning after a significant gap, treat this as a fresh start with prior context`;
26
+ }
27
+
28
+ // Create the MCP server
29
+ const server = new Server(
30
+ {
31
+ name: "mcp-time-context",
32
+ version: "1.0.0",
33
+ },
34
+ {
35
+ capabilities: {
36
+ tools: {},
37
+ },
38
+ }
39
+ );
40
+
41
+ // List available tools
42
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
43
+ return {
44
+ tools: [
45
+ {
46
+ name: "get_time_context",
47
+ description:
48
+ "Returns the current date, time, timezone, and how long it has been since the user last sent a message. Use this at the start of every conversation turn to understand temporal context.",
49
+ inputSchema: {
50
+ type: "object",
51
+ properties: {},
52
+ required: [],
53
+ },
54
+ },
55
+ ],
56
+ };
57
+ });
58
+
59
+ // Handle tool calls
60
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
61
+ if (request.params.name === "get_time_context") {
62
+ const now = new Date();
63
+
64
+ // Build time gap context
65
+ let gapContext = "This is the first message in this session.";
66
+ if (lastMessageTime) {
67
+ gapContext = `User's last message was ${describeTimeGap(lastMessageTime, now)}`;
68
+ }
69
+
70
+ // Update last message time
71
+ lastMessageTime = now;
72
+
73
+ const context = {
74
+ current_date: now.toLocaleDateString("en-US", {
75
+ weekday: "long",
76
+ year: "numeric",
77
+ month: "long",
78
+ day: "numeric",
79
+ }),
80
+ current_time: now.toLocaleTimeString("en-US", {
81
+ hour: "2-digit",
82
+ minute: "2-digit",
83
+ timeZoneName: "short",
84
+ }),
85
+ iso_timestamp: now.toISOString(),
86
+ unix_timestamp: Math.floor(now.getTime() / 1000),
87
+ conversation_gap: gapContext,
88
+ instruction:
89
+ "Use this temporal context to respond naturally. If the user is returning after hours or days, acknowledge the time gap subtly and don't assume conversation continuity.",
90
+ };
91
+
92
+ return {
93
+ content: [
94
+ {
95
+ type: "text",
96
+ text: JSON.stringify(context, null, 2),
97
+ },
98
+ ],
99
+ };
100
+ }
101
+
102
+ throw new Error(`Unknown tool: ${request.params.name}`);
103
+ });
104
+
105
+ // Start the server
106
+ async function main() {
107
+ const transport = new StdioServerTransport();
108
+ await server.connect(transport);
109
+ console.error("mcp-time-context server running...");
110
+ }
111
+
112
+ main().catch((error) => {
113
+ console.error("Fatal error:", error);
114
+ process.exit(1);
115
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "resolveJsonModule": true,
11
+ "skipLibCheck": true
12
+ },
13
+ "include": ["src/**/*"],
14
+ "exclude": ["node_modules", "dist"]
15
+ }