A Model Context Protocol (MCP) server for current and local time management across multiple cities and timezones.
McpTimeTools is a .NET 8 MCP server that provides timezone-aware time utilities. It supports retrieving current UTC time and local times for various cities worldwide, with an extensible architecture for adding custom city-timezone mappings.
- Current UTC Time: Get the current time in UTC format
- City-Based Local Time: Retrieve local time for predefined cities
- Extensible Timezone Mapping: Add or update custom city-timezone mappings
- Robust Error Handling: Custom exception types for clear error diagnostics
- Type-Safe: Built with C# 12 and nullable reference types
- Dependency Injection: Modern .NET patterns with DI support
- Fully Tested: Comprehensive unit test coverage
- Cancun (
America/Cancun) - Mexico City (
America/Mexico_City) - New York (
America/New_York) - London (
Europe/London) - Tokyo (
Asia/Tokyo)
- .NET 8 SDK or later
Clone the repository:
git clone https://github.com/LouisGheysensCodit/McpTimeTools.git
cd McpTimeTools/src/McpTimeServerdotnet builddotnet rundotnet testThe server exposes the following MCP tools:
Gets the current UTC time.
Returns: Current UTC time in yyyy-MM-dd HH:mm:ss format
Example:
2024-01-15 14:30:45
Gets the local time for a specified city.
Parameters:
city(string): Name of the city
Returns: Formatted string with city name, local time, and timezone ID
Example:
Tokyo: 2024-01-15 23:30:45 (Asia/Tokyo)
// Create a timezone provider
var timeZoneProvider = new TimeZoneProvider();
// Get timezone ID for a city
var timezoneId = timeZoneProvider.GetTimeZoneId("London");
// Returns: "Europe/London"
// Try to get timezone ID
if (timeZoneProvider.TryGetTimeZoneId("Paris", out var tz))
{
Console.WriteLine($"Timezone: {tz}");
}
// Add a custom city
timeZoneProvider.AddOrUpdateCity("Paris", "Europe/Paris");
// Get all available cities
var cities = timeZoneProvider.GetAvailableCities();Gets a comma-separated list of all available city names.
Parameters:
sortOrder(CitySortOrder, optional): Specifies how cities are sorted.
Defaults toAlphabetical(A–Z). Possible values:None— returns cities in their insertion orderAlphabetical— ascending (A–Z)AlphabeticalDescending— descending (Z–A)
Returns:
Comma-separated list of city names, or "No cities configured." if none exist.
Example: Cancun, London, Mexico City, New York, Tokyo
Notes:
- Useful for lightweight city listings or populating dropdown menus in clients.
- Throws
InvalidCitySortOrderExceptionif an unsupported sort order is provided.
McpTimeServer/
??? Program.cs # Application entry point
??? TimeTools.cs # MCP tool implementations
??? ITimeZoneProvider.cs # Timezone provider interface
??? TimeZoneProvider.cs # Timezone provider implementation
??? Exceptions/
? ??? TimeZoneException.cs # Base exception
? ??? InvalidCityException.cs # Invalid city name exception
? ??? InvalidTimeZoneIdException.cs # Invalid timezone ID exception
? ??? CityNotFoundException.cs # City not found exception
??? McpTimeServer.Tests/
??? TimeToolsTests.cs # TimeTools unit tests
??? TimeZoneProviderTests.cs # TimeZoneProvider unit tests
TimeTools: MCP server tool class providing time-related operationsITimeZoneProvider: Interface for timezone mapping operationsTimeZoneProvider: Default implementation with predefined cities- Custom Exceptions: Domain-specific exceptions for better error handling
Exception
??? TimeZoneException (abstract base)
??? InvalidCityException
??? InvalidTimeZoneIdException
??? CityNotFoundException
??? InvalidCitySortOrderException
- .NET 8: Target framework
- C# 12: Language version with modern features
- OllamaSharp.ModelContextProtocol: MCP server implementation
- Microsoft.Extensions.Hosting: Hosting infrastructure
- xUnit: Testing framework
The project includes comprehensive unit tests covering:
- ? Valid and invalid city lookups
- ? Case-insensitive city matching
- ? Custom exception scenarios
- ? Available cities retrieval
- ? City mapping updates
- ? Edge cases (null, empty, whitespace)
Test Coverage: 22 tests, all passing ?
try
{
var tz = provider.GetTimeZoneId("InvalidCity");
}
catch (CityNotFoundException ex)
{
Console.WriteLine($"City '{ex.CityName}' not found!");
Console.WriteLine($"Available: {string.Join(", ", ex.AvailableCities)}");
}
catch (InvalidCityException ex)
{
Console.WriteLine($"Invalid city name: {ex.CityName}");
}var provider = new TimeZoneProvider();
// Add a new city
provider.AddOrUpdateCity("Berlin", "Europe/Berlin");
provider.AddOrUpdateCity("Sydney", "Australia/Sydney");
// Use the new cities
var berlinTime = provider.GetTimeZoneId("Berlin");Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Louis Gheysens
- GitHub: @LouisGheysensCodit
- Built with OllamaSharp.ModelContextProtocol
- Powered by .NET 8
? If you find this project useful, please consider giving it a star!