index.ts•6.79 kB
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
Tool,
} from '@modelcontextprotocol/sdk/types.js';
import { TimeService } from './time-service.js';
import { GetCurrentTimeParams, ConvertTimeParams } from './interfaces.js';
const server = new Server(
{
name: 'time-node-mcp',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
const tools: Tool[] = [
{
name: 'get_current_time',
description: 'Get the current date and time in a specific timezone with various formatting options',
inputSchema: {
type: 'object',
properties: {
timezone: {
type: 'string',
description: 'IANA timezone identifier (e.g., "America/New_York", "Europe/London", "Asia/Tokyo")',
},
format: {
type: 'string',
enum: ['iso', 'local', 'full'],
description: 'Output format: "iso" for ISO 8601, "local" for MM/DD/YYYY HH:MM:SS, "full" for human-readable',
default: 'iso',
},
},
required: ['timezone'],
},
},
{
name: 'convert_time',
description: 'Convert time from one timezone to another',
inputSchema: {
type: 'object',
properties: {
sourceTimezone: {
type: 'string',
description: 'Source IANA timezone identifier',
},
targetTimezone: {
type: 'string',
description: 'Target IANA timezone identifier',
},
time: {
type: 'string',
description: 'Time in HH:MM or HH:MM:SS format (24-hour)',
},
date: {
type: 'string',
description: 'Optional date in YYYY-MM-DD format. If not provided, uses current date',
},
},
required: ['sourceTimezone', 'targetTimezone', 'time'],
},
},
{
name: 'get_system_timezone',
description: 'Get the system\'s current timezone',
inputSchema: {
type: 'object',
properties: {},
},
},
{
name: 'get_current_date',
description: 'Get the current date in a specific timezone with day of week information',
inputSchema: {
type: 'object',
properties: {
timezone: {
type: 'string',
description: 'IANA timezone identifier (e.g., "America/New_York", "Europe/London")',
},
includeTime: {
type: 'boolean',
description: 'Whether to include time information',
default: false,
},
},
required: ['timezone'],
},
},
];
server.setRequestHandler(ListToolsRequestSchema, async () => {
return { tools };
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case 'get_current_time': {
const { timezone, format = 'iso' } = (args as unknown) as GetCurrentTimeParams;
const result = TimeService.getCurrentTime(timezone, format);
return {
content: [
{
type: 'text',
text: JSON.stringify({
timezone: result.timezone,
datetime: result.datetime,
isDST: result.isDST,
utcOffset: result.utcOffset,
localizedFormat: result.localizedFormat,
format: format,
}, null, 2),
},
],
};
}
case 'convert_time': {
const { sourceTimezone, targetTimezone, time, date } = (args as unknown) as ConvertTimeParams;
const result = TimeService.convertTime(sourceTimezone, targetTimezone, time, date);
return {
content: [
{
type: 'text',
text: JSON.stringify({
conversion: {
source: result.source,
target: result.target,
timeDifference: result.timeDifference,
},
}, null, 2),
},
],
};
}
case 'get_system_timezone': {
const systemTimezone = TimeService.getSystemTimezone();
const currentTime = TimeService.getCurrentTime(systemTimezone, 'full');
return {
content: [
{
type: 'text',
text: JSON.stringify({
systemTimezone,
currentTime: currentTime.localizedFormat,
utcOffset: currentTime.utcOffset,
isDST: currentTime.isDST,
}, null, 2),
},
],
};
}
case 'get_current_date': {
const { timezone, includeTime = false } = args as { timezone: string; includeTime?: boolean };
TimeService.validateTimezone(timezone);
const now = new Date();
const dateInfo = {
timezone,
date: now.toLocaleDateString('en-US', {
timeZone: timezone,
year: 'numeric',
month: '2-digit',
day: '2-digit'
}),
dayOfWeek: now.toLocaleDateString('en-US', {
timeZone: timezone,
weekday: 'long'
}),
fullDate: now.toLocaleDateString('en-US', {
timeZone: timezone,
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
}),
};
if (includeTime) {
const timeInfo = TimeService.getCurrentTime(timezone, 'full');
Object.assign(dateInfo, {
time: timeInfo.datetime,
fullDateTime: timeInfo.localizedFormat,
isDST: timeInfo.isDST,
utcOffset: timeInfo.utcOffset,
});
}
return {
content: [
{
type: 'text',
text: JSON.stringify(dateInfo, null, 2),
},
],
};
}
default:
throw new Error(`Unknown tool: ${name}`);
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
return {
content: [
{
type: 'text',
text: JSON.stringify({
error: errorMessage,
tool: name,
arguments: args,
}, null, 2),
},
],
isError: true,
};
}
});
async function main(): Promise<void> {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('Time Node MCP Server running on stdio');
}
main().catch((error) => {
console.error('Server error:', error);
process.exit(1);
});