mcp-datetime-ruby 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6de1db88b3a1ab058beed308b8f6f5dc13182e21bd1583dddab47cd3163bf6b5
4
+ data.tar.gz: f1e050574dc6efb282a8855ecd75122f981a2996c9c7c8614a96169298abdd3c
5
+ SHA512:
6
+ metadata.gz: 7691d9741f8f531497fb0a910766bb4ce138724af591b3e55dada6acd144e1475899f8aba30d4ece79b842093db797c5f2bbe314e90cc21f7b4bfba611e82f3a
7
+ data.tar.gz: 36890bbf01deff8516c58030897faf98d06bad558b65e6b66ac82103ec21782ad67bcf52b6c94842e61a2363dca8f97be5bbc4a231bcd1133ee9aabed0065f12
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2025-06-10
9
+
10
+ ### Added
11
+ - Initial release
12
+ - MCP server implementation for datetime tools
13
+ - `get_current_datetime` tool with multiple format options
14
+ - `get_date_info` tool for detailed date information
15
+ - Support for timezone handling
16
+ - Debug logging to `/tmp/mcp_datetime_debug.log`
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Wolfgang Teuber
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,322 @@
1
+ # MCP DateTime Ruby
2
+
3
+ A Ruby implementation of an MCP (Model Context Protocol) server that provides datetime tools for AI assistants. This server enables AI assistants to get current date/time information and detailed date information in various formats.
4
+
5
+ ## Features
6
+
7
+ - Get current date and time in multiple formats (ISO, human-readable, Unix timestamp, etc.)
8
+ - Support for timezone conversions
9
+ - Detailed date information (weekday, quarter, leap year status, etc.)
10
+ - Full MCP protocol compliance
11
+ - Automatic executable installation via RubyGems plugin
12
+
13
+ ## Requirements
14
+
15
+ - Ruby 3.1.0 or higher
16
+ - Bundler
17
+
18
+ ## Installation
19
+
20
+ ### From RubyGems (Once Published)
21
+
22
+ ```bash
23
+ gem install mcp-datetime-ruby
24
+ ```
25
+
26
+ The gem will automatically install an executable at `~/bin/mcp-datetime-ruby` during installation.
27
+
28
+ ### Local Installation (Development)
29
+
30
+ 1. **Clone the repository**:
31
+ ```bash
32
+ git clone https://github.com/wteuber/mcp-datetime-ruby.git
33
+ cd mcp-datetime-ruby
34
+ ```
35
+
36
+ 2. **Install dependencies**:
37
+ ```bash
38
+ bundle install
39
+ ```
40
+
41
+ 3. **Build and install the gem locally**:
42
+ ```bash
43
+ gem build mcp-datetime-ruby.gemspec
44
+ gem install ./mcp-datetime-ruby-0.1.0.gem
45
+ ```
46
+
47
+ This will automatically create the executable at `~/bin/mcp-datetime-ruby`.
48
+
49
+ 4. **Or run directly without installing**:
50
+ ```bash
51
+ # Run directly from the repository
52
+ ./bin/mcp-datetime-ruby
53
+
54
+ # Or with bundle exec
55
+ bundle exec ruby bin/mcp-datetime-ruby
56
+ ```
57
+
58
+ ### Verifying Installation
59
+
60
+ After installation, verify the executable is available:
61
+
62
+ ```bash
63
+ # Check if the executable exists
64
+ which mcp-datetime-ruby
65
+
66
+ # Or if ~/bin is not in your PATH
67
+ ls ~/bin/mcp-datetime-ruby
68
+ ```
69
+
70
+ ## Configuration
71
+
72
+ ### Adding to Cursor
73
+
74
+ To use this MCP server with Cursor:
75
+
76
+ 1. **Open your MCP configuration file**:
77
+ ```bash
78
+ # Create the file if it doesn't exist
79
+ touch ~/.cursor/mcp.json
80
+ ```
81
+
82
+ 2. **Add the datetime server configuration**:
83
+
84
+ If `~/bin` is in your PATH:
85
+ ```json
86
+ {
87
+ "mcpServers": {
88
+ "datetime": {
89
+ "command": "mcp-datetime-ruby"
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ If you need to use the full path:
96
+ ```json
97
+ {
98
+ "mcpServers": {
99
+ "datetime": {
100
+ "command": "/Users/yourusername/bin/mcp-datetime-ruby"
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ If running from the repository directly:
107
+ ```json
108
+ {
109
+ "mcpServers": {
110
+ "datetime": {
111
+ "command": "/path/to/mcp-datetime-ruby/bin/mcp-datetime-ruby"
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ 3. **If you have existing MCP servers**, add to the existing configuration:
118
+ ```json
119
+ {
120
+ "mcpServers": {
121
+ "existing-server": {
122
+ "command": "existing-command"
123
+ },
124
+ "datetime": {
125
+ "command": "mcp-datetime-ruby"
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
131
+ 4. **Restart Cursor** for the changes to take effect.
132
+
133
+ 5. **Verify the server is working** by asking the AI to "get the current time" or "what's today's date".
134
+
135
+ ## Available Tools
136
+
137
+ ### `get_current_datetime`
138
+
139
+ Get the current date and time in various formats.
140
+
141
+ **Parameters:**
142
+ - `format` (optional): Output format
143
+ - `iso` (default): ISO 8601 format (e.g., "2024-01-15T14:30:45-05:00")
144
+ - `human`: Human-readable format (e.g., "January 15, 2024 at 02:30 PM")
145
+ - `date_only`: Date only (e.g., "2024-01-15")
146
+ - `time_only`: Time only (e.g., "14:30:45")
147
+ - `unix`: Unix timestamp (e.g., "1705342245")
148
+ - `timezone` (optional): IANA timezone name (e.g., "America/New_York", "Europe/London", "Asia/Tokyo")
149
+
150
+ **Example Response:**
151
+ ```json
152
+ {
153
+ "datetime": "2024-01-15T14:30:45-05:00",
154
+ "timestamp": 1705342245.123456,
155
+ "year": 2024,
156
+ "month": 1,
157
+ "day": 15,
158
+ "hour": 14,
159
+ "minute": 30,
160
+ "second": 45,
161
+ "weekday": "Monday",
162
+ "timezone": "EST"
163
+ }
164
+ ```
165
+
166
+ ### `get_date_info`
167
+
168
+ Get detailed information about the current date.
169
+
170
+ **Parameters:** None
171
+
172
+ **Example Response:**
173
+ ```json
174
+ {
175
+ "date": "2024-01-15",
176
+ "year": 2024,
177
+ "month": 1,
178
+ "month_name": "January",
179
+ "day": 15,
180
+ "weekday": "Monday",
181
+ "weekday_number": 1,
182
+ "day_of_year": 15,
183
+ "week_of_year": 3,
184
+ "quarter": 1,
185
+ "is_weekend": false,
186
+ "is_leap_year": true,
187
+ "days_in_month": 31,
188
+ "timezone": "EST"
189
+ }
190
+ ```
191
+
192
+ ## Development
193
+
194
+ ### Setup
195
+
196
+ After cloning the repository:
197
+
198
+ ```bash
199
+ # Install dependencies
200
+ bundle install
201
+
202
+ # Run tests to verify everything is working
203
+ bundle exec rake test
204
+ ```
205
+
206
+ ### Code Style
207
+
208
+ This project uses RuboCop for code style enforcement. Run RuboCop to check for style violations:
209
+
210
+ ```bash
211
+ # Check for style violations
212
+ bundle exec rubocop
213
+
214
+ # Auto-correct correctable violations
215
+ bundle exec rubocop -a
216
+
217
+ # Auto-correct with more aggressive corrections
218
+ bundle exec rubocop -A
219
+ ```
220
+
221
+ The project includes a `.rubocop.yml` configuration file that customizes the rules for this codebase.
222
+
223
+ ### Running Tests
224
+
225
+ The gem includes comprehensive tests using Minitest:
226
+
227
+ ```bash
228
+ # Run unit tests only (default)
229
+ bundle exec rake test
230
+
231
+ # Run integration tests only
232
+ bundle exec rake integration
233
+
234
+ # Run all tests (unit + integration)
235
+ bundle exec rake test_all
236
+
237
+ # Run tests with verbose output
238
+ bundle exec rake test TESTOPTS="--verbose"
239
+
240
+ # Run a specific test file
241
+ bundle exec ruby -Ilib:test test/mcp/datetime/server_test.rb
242
+ ```
243
+
244
+ The test suite includes:
245
+ - Unit tests for all MCP protocol methods
246
+ - Tests for each datetime format and timezone handling
247
+ - Edge case and error handling tests
248
+ - RubyGems plugin tests
249
+ - Integration tests for full server communication
250
+
251
+ ### Building the Gem
252
+
253
+ ```bash
254
+ # Build the gem
255
+ gem build mcp-datetime-ruby.gemspec
256
+
257
+ # Install locally for testing
258
+ gem install ./mcp-datetime-ruby-0.1.0.gem
259
+ ```
260
+
261
+ ### Debugging
262
+
263
+ The server logs debug information to `/tmp/mcp_datetime_debug.log`. You can tail this file to see server activity:
264
+
265
+ ```bash
266
+ tail -f /tmp/mcp_datetime_debug.log
267
+ ```
268
+
269
+ ## Uninstalling
270
+
271
+ ### Uninstall the Gem
272
+
273
+ ```bash
274
+ # Uninstall the gem (this will also remove the executable from ~/bin)
275
+ gem uninstall mcp-datetime-ruby
276
+
277
+ # If multiple versions are installed
278
+ gem uninstall mcp-datetime-ruby --all
279
+ ```
280
+
281
+ ### Remove from Cursor Configuration
282
+
283
+ Remove the datetime server entry from `~/.cursor/mcp.json`:
284
+
285
+ ```json
286
+ {
287
+ "mcpServers": {
288
+ // Remove this entire "datetime" section
289
+ "datetime": {
290
+ "command": "mcp-datetime-ruby"
291
+ }
292
+ }
293
+ }
294
+ ```
295
+
296
+ ### Clean Up Development Files
297
+
298
+ If you cloned the repository:
299
+
300
+ ```bash
301
+ # Remove the cloned repository
302
+ rm -rf /path/to/mcp-datetime-ruby
303
+
304
+ # Remove any locally built gem files
305
+ rm mcp-datetime-ruby-*.gem
306
+ ```
307
+
308
+ ## Contributing
309
+
310
+ Bug reports and pull requests are welcome on GitHub at https://github.com/wteuber/mcp-datetime-ruby.
311
+
312
+ 1. Fork the repository
313
+ 2. Create your feature branch (`git checkout -b feature/my-new-feature`)
314
+ 3. Write tests for your changes
315
+ 4. Make your changes and ensure all tests pass
316
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
317
+ 6. Push to the branch (`git push origin feature/my-new-feature`)
318
+ 7. Create a new Pull Request
319
+
320
+ ## License
321
+
322
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'mcp', 'datetime'))
5
+
6
+ # Run the MCP DateTime server
7
+ server = MCP::DateTime::Server.new
8
+ server.run
@@ -0,0 +1,294 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'tools'
5
+
6
+ module MCP
7
+ module DateTime
8
+ # MCP DateTime Server implementation
9
+ # Provides datetime tools via the Model Context Protocol
10
+ class Server
11
+ include Tools
12
+
13
+ LOG_FILE = '/tmp/mcp_datetime_debug.log'
14
+
15
+ def initialize
16
+ @server_info = {
17
+ name: 'mcp-datetime-ruby',
18
+ version: VERSION
19
+ }
20
+ setup_io_streams
21
+ setup_signal_handlers
22
+ log_startup_info
23
+ end
24
+
25
+ def run
26
+ warn '[MCP::DateTime] Starting server...'
27
+ process_requests
28
+ warn '[MCP::DateTime] Server stopped'
29
+ end
30
+
31
+ private
32
+
33
+ def setup_io_streams
34
+ $stderr.sync = true
35
+ $stdout.sync = true
36
+ end
37
+
38
+ def setup_signal_handlers
39
+ Signal.trap('INT') { exit(0) }
40
+ Signal.trap('TERM') { exit(0) }
41
+ end
42
+
43
+ def log_startup_info
44
+ log("Starting MCP DateTime server (Ruby #{RUBY_VERSION})")
45
+ log("Script location: #{__FILE__}")
46
+ log("Working directory: #{Dir.pwd}")
47
+ log("Environment: #{ENV.to_h}")
48
+ end
49
+
50
+ def process_requests
51
+ loop do
52
+ line = read_request
53
+ next unless line
54
+
55
+ handle_request_line(line)
56
+ rescue JSON::ParserError => e
57
+ handle_parse_error(e)
58
+ rescue Interrupt
59
+ handle_interrupt
60
+ rescue StandardError => e
61
+ handle_error(e)
62
+ end
63
+ end
64
+
65
+ def read_request
66
+ line = $stdin.gets
67
+ if line.nil?
68
+ handle_eof
69
+ return nil
70
+ end
71
+ line.strip.empty? ? nil : line
72
+ end
73
+
74
+ def handle_eof
75
+ log('EOF received, shutting down gracefully')
76
+ warn '[MCP::DateTime] EOF received, shutting down gracefully'
77
+ exit(0)
78
+ end
79
+
80
+ def handle_request_line(line)
81
+ request = JSON.parse(line.strip)
82
+ log("Received request: #{request['method']}")
83
+ warn "[MCP::DateTime] Received request: #{request['method']}"
84
+
85
+ response = handle_request(request)
86
+ send_response(request, response)
87
+ end
88
+
89
+ def send_response(request, response)
90
+ return unless request['id'] && response
91
+
92
+ $stdout.puts(JSON.generate(response))
93
+ $stdout.flush
94
+ end
95
+
96
+ def handle_parse_error(error)
97
+ log("Parse error: #{error.message}")
98
+ error_response = build_error_response(-32_700, "Parse error: #{error.message}")
99
+ $stdout.puts(JSON.generate(error_response))
100
+ $stdout.flush
101
+ end
102
+
103
+ def handle_interrupt
104
+ log('Interrupted, shutting down')
105
+ warn '[MCP::DateTime] Interrupted, shutting down'
106
+ exit(0)
107
+ end
108
+
109
+ def handle_error(error)
110
+ log("Error: #{error.message}")
111
+ log(error.backtrace.join("\n"))
112
+ warn "[MCP::DateTime] Error: #{error.message}"
113
+ warn error.backtrace.join("\n")
114
+ end
115
+
116
+ def log(message)
117
+ File.open(LOG_FILE, 'a') do |f|
118
+ f.puts "[#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}] #{message}"
119
+ end
120
+ rescue StandardError => e
121
+ warn "Failed to write to log: #{e.message}"
122
+ end
123
+
124
+ def handle_request(request)
125
+ method = request['method']
126
+ params = request['params'] || {}
127
+ id = request['id']
128
+
129
+ return handle_notification(method) if notification?(method)
130
+
131
+ result = dispatch_method(method, params)
132
+ build_success_response(result, id)
133
+ rescue StandardError => e
134
+ build_error_response(-32_603, e.message, id)
135
+ end
136
+
137
+ def notification?(method)
138
+ method == 'notifications/initialized'
139
+ end
140
+
141
+ def handle_notification(method)
142
+ return unless method == 'notifications/initialized'
143
+
144
+ log('Client initialized notification received')
145
+ warn '[MCP::DateTime] Client initialized notification received'
146
+ nil
147
+ end
148
+
149
+ def dispatch_method(method, params)
150
+ case method
151
+ when 'initialize'
152
+ handle_initialize(params)
153
+ when 'tools/list'
154
+ handle_list_tools
155
+ when 'tools/call'
156
+ handle_call_tool(params)
157
+ else
158
+ raise "Unknown method: #{method}"
159
+ end
160
+ end
161
+
162
+ def build_success_response(result, id)
163
+ {
164
+ jsonrpc: '2.0',
165
+ result:,
166
+ id:
167
+ }
168
+ end
169
+
170
+ def build_error_response(code, message, id = nil)
171
+ {
172
+ jsonrpc: '2.0',
173
+ error: {
174
+ code:,
175
+ message:
176
+ },
177
+ id:
178
+ }
179
+ end
180
+
181
+ def handle_initialize(_params)
182
+ {
183
+ protocolVersion: '2024-11-05',
184
+ capabilities: {
185
+ tools: {
186
+ listChanged: false
187
+ }
188
+ },
189
+ serverInfo: @server_info
190
+ }
191
+ end
192
+
193
+ def handle_list_tools
194
+ {
195
+ tools: [
196
+ datetime_tool_definition,
197
+ date_info_tool_definition
198
+ ]
199
+ }
200
+ end
201
+
202
+ def handle_call_tool(params)
203
+ tool_name = params['name']
204
+ arguments = params['arguments'] || {}
205
+
206
+ case tool_name
207
+ when 'get_current_datetime'
208
+ current_datetime(arguments)
209
+ when 'get_date_info'
210
+ date_info
211
+ else
212
+ raise "Unknown tool: #{tool_name}"
213
+ end
214
+ end
215
+
216
+ def current_datetime(arguments)
217
+ format_type = arguments['format'] || 'iso'
218
+ timezone = arguments['timezone']
219
+
220
+ now = get_time_in_timezone(timezone)
221
+ formatted = format_datetime(now, format_type)
222
+
223
+ build_content_response(datetime_data(now, formatted))
224
+ end
225
+
226
+ def get_time_in_timezone(timezone)
227
+ ENV['TZ'] = timezone if timezone
228
+ Time.now
229
+ end
230
+
231
+ def format_datetime(time, format_type)
232
+ case format_type
233
+ when 'human' then time.strftime('%B %d, %Y at %I:%M %p')
234
+ when 'date_only' then time.strftime('%Y-%m-%d')
235
+ when 'time_only' then time.strftime('%H:%M:%S')
236
+ when 'unix' then time.to_i.to_s
237
+ else time.iso8601
238
+ end
239
+ end
240
+
241
+ def datetime_data(time, formatted)
242
+ {
243
+ datetime: formatted,
244
+ timestamp: time.to_f,
245
+ year: time.year,
246
+ month: time.month,
247
+ day: time.day,
248
+ hour: time.hour,
249
+ minute: time.min,
250
+ second: time.sec,
251
+ weekday: time.strftime('%A'),
252
+ timezone: time.zone
253
+ }
254
+ end
255
+
256
+ def date_info
257
+ now = Time.now
258
+ today = Date.today
259
+
260
+ build_content_response(date_info_data(today, now))
261
+ end
262
+
263
+ def date_info_data(date, time)
264
+ {
265
+ date: date.to_s,
266
+ year: date.year,
267
+ month: date.month,
268
+ month_name: date.strftime('%B'),
269
+ day: date.day,
270
+ weekday: date.strftime('%A'),
271
+ weekday_number: date.wday,
272
+ day_of_year: date.yday,
273
+ week_of_year: date.cweek,
274
+ quarter: ((date.month - 1) / 3) + 1,
275
+ is_weekend: [0, 6].include?(date.wday),
276
+ is_leap_year: date.leap?,
277
+ days_in_month: Date.new(date.year, date.month, -1).day,
278
+ timezone: time.zone
279
+ }
280
+ end
281
+
282
+ def build_content_response(data)
283
+ {
284
+ content: [
285
+ {
286
+ type: 'text',
287
+ text: JSON.pretty_generate(data)
288
+ }
289
+ ]
290
+ }
291
+ end
292
+ end
293
+ end
294
+ end
@@ -0,0 +1,41 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ module MCP
5
+ module DateTime
6
+ # Tool definitions for the MCP DateTime server
7
+ module Tools
8
+ def datetime_tool_definition
9
+ {
10
+ name: 'get_current_datetime',
11
+ description: 'Get the current date and time',
12
+ inputSchema: {
13
+ type: 'object',
14
+ properties: {
15
+ format: {
16
+ type: 'string',
17
+ description: 'Optional datetime format',
18
+ enum: %w[iso human date_only time_only unix]
19
+ },
20
+ timezone: {
21
+ type: 'string',
22
+ description: 'Optional timezone (e.g., "America/New_York", "Europe/London")'
23
+ }
24
+ }
25
+ }
26
+ }
27
+ end
28
+
29
+ def date_info_tool_definition
30
+ {
31
+ name: 'get_date_info',
32
+ description: 'Get detailed information about the current date',
33
+ inputSchema: {
34
+ type: 'object',
35
+ properties: {}
36
+ }
37
+ }
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,8 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ module MCP
5
+ module DateTime
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require 'json'
5
+ require 'time'
6
+ require 'date'
7
+ require_relative 'datetime/version'
8
+ require_relative 'datetime/server'
9
+
10
+ module MCP
11
+ module DateTime
12
+ class Error < StandardError; end
13
+ end
14
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubygems'
4
+ require 'fileutils'
5
+
6
+ # This plugin creates an executable file after gem installation
7
+ Gem.post_install do |installer|
8
+ next unless installer.spec.name == 'mcp-datetime-ruby'
9
+
10
+ # Get the gem's installation directory
11
+ gem_dir = installer.spec.gem_dir
12
+
13
+ # Create the executable content with the proper paths
14
+ executable_content = <<~RUBY
15
+ #!#{Gem.ruby}
16
+ # frozen_string_literal: true
17
+
18
+ # Add the gem's lib directory to the load path
19
+ $LOAD_PATH.unshift("#{gem_dir}/lib")
20
+
21
+ require 'json'
22
+ require 'date'
23
+ require 'time'
24
+ require 'mcp/datetime/version'
25
+ require 'mcp/datetime/server'
26
+
27
+ # Run the server
28
+ MCP::DateTime::Server.new.run
29
+ RUBY
30
+
31
+ # Determine the bin directory in user's home
32
+ home_bin_dir = File.expand_path('~/bin')
33
+ executable_path = File.join(home_bin_dir, 'mcp-datetime-ruby')
34
+
35
+ # Create the bin directory if it doesn't exist
36
+ FileUtils.mkdir_p(home_bin_dir) unless File.directory?(home_bin_dir)
37
+
38
+ # Check if executable already exists
39
+ if File.exist?(executable_path)
40
+ puts "Updating existing executable: #{executable_path}"
41
+ else
42
+ puts "Creating new executable: #{executable_path}"
43
+ end
44
+
45
+ # Write the executable file
46
+ File.write(executable_path, executable_content)
47
+
48
+ # Make it executable
49
+ File.chmod(0o755, executable_path)
50
+
51
+ puts "Executable ready at: #{executable_path}"
52
+ puts 'Make sure ~/bin is in your PATH to use the executable' unless ENV['PATH'].include?(home_bin_dir)
53
+ end
54
+
55
+ # Clean up the executable on uninstall
56
+ Gem.pre_uninstall do |uninstaller|
57
+ next unless uninstaller.spec.name == 'mcp-datetime-ruby'
58
+
59
+ executable_path = File.expand_path('~/bin/mcp-datetime-ruby')
60
+
61
+ if File.exist?(executable_path)
62
+ File.delete(executable_path)
63
+ puts "Removed executable: #{executable_path}"
64
+ end
65
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mcp-datetime-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Wolfgang Teuber
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-06-10 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: json
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '2.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: bundler
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: minitest
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '5.0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '5.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rake
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '13.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '13.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rubocop
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.0'
82
+ description: A Ruby implementation of an MCP server that provides datetime tools for
83
+ AI assistants
84
+ email:
85
+ - knugie@gmx.net
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - CHANGELOG.md
91
+ - LICENSE.txt
92
+ - README.md
93
+ - bin/mcp-datetime-ruby
94
+ - lib/mcp/datetime.rb
95
+ - lib/mcp/datetime/server.rb
96
+ - lib/mcp/datetime/tools.rb
97
+ - lib/mcp/datetime/version.rb
98
+ - lib/rubygems_plugin.rb
99
+ homepage: https://github.com/wteuber/mcp-datetime-ruby
100
+ licenses:
101
+ - MIT
102
+ metadata:
103
+ homepage_uri: https://github.com/wteuber/mcp-datetime-ruby
104
+ source_code_uri: https://github.com/wteuber/mcp-datetime-ruby
105
+ changelog_uri: https://github.com/wteuber/mcp-datetime-ruby/blob/main/CHANGELOG.md
106
+ rubygems_mfa_required: 'true'
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: 3.1.0
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubygems_version: 3.6.2
122
+ specification_version: 4
123
+ summary: MCP (Model Context Protocol) DateTime Server for Ruby
124
+ test_files: []