things-mcp 0.1.0 → 0.1.2
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 +4 -4
- data/Gemfile +1 -0
- data/README.md +61 -26
- data/bin/test_connection +6 -3
- data/bin/things_mcp_server +3 -2
- data/lib/things_mcp/database.rb +41 -35
- data/lib/things_mcp/formatters.rb +0 -1
- data/lib/things_mcp/handlers.rb +7 -7
- data/lib/things_mcp/server.rb +16 -13
- data/lib/things_mcp/url_scheme.rb +1 -3
- data/lib/things_mcp/version.rb +5 -0
- data/lib/things_mcp.rb +6 -6
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66584b39e6d5286abeb4a75f08f029bab5c7c1b7b7f42129ee12986086fa7927
|
4
|
+
data.tar.gz: bb7603686e15d0dc366f746e263dbb99cebb00ce35377e8ae49fb7f468658dc0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ff846805290fb8e7e628b8809855c2538852be5f0ea69766d176fa6065081ae93af010b2958c68bdc4ce5014f580375939701bf7964a1d915ea3d72d0d5f30e
|
7
|
+
data.tar.gz: 8450f45b5c44b9cf8a37762e48cb7c4fe2b64a6e409ebcd2603036726c49535ad862b9ded6796dc13788694562c10e1406ec7547c7364c1bfa1d91b61312b8e9
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Things 3 MCP Server (Ruby)
|
2
2
|
|
3
|
-
A Model Context Protocol (MCP) server for Things 3, implemented in Ruby.
|
3
|
+
A (clunky) Model Context Protocol (MCP) server for Things 3, implemented in Ruby.
|
4
4
|
|
5
5
|
## Features
|
6
6
|
|
@@ -16,19 +16,22 @@ A Model Context Protocol (MCP) server for Things 3, implemented in Ruby.
|
|
16
16
|
2. **Ruby 3.2+** installed (required by the MCP gem dependency)
|
17
17
|
3. **No authentication required** - the server reads from Things' local database
|
18
18
|
|
19
|
-
|
20
|
-
> ```bash
|
21
|
-
> # Using Homebrew (recommended)
|
22
|
-
> brew install ruby
|
23
|
-
>
|
24
|
-
> # Or using rbenv
|
25
|
-
> brew install rbenv
|
26
|
-
> rbenv install 3.4.1
|
27
|
-
> rbenv global 3.4.1
|
28
|
-
> ```
|
19
|
+
**Note for macOS users**: The system Ruby is possibly too old. Install a modern Ruby.
|
29
20
|
|
30
21
|
## Installation
|
31
22
|
|
23
|
+
### Option 1: Using the Released Gem (Recommended)
|
24
|
+
|
25
|
+
1. Install the gem:
|
26
|
+
|
27
|
+
```bash
|
28
|
+
gem install things-mcp
|
29
|
+
```
|
30
|
+
|
31
|
+
2. The MCP server will be available as `things_mcp_server` in your PATH.
|
32
|
+
|
33
|
+
### Option 2: From Source
|
34
|
+
|
32
35
|
1. Clone this repository:
|
33
36
|
|
34
37
|
```bash
|
@@ -56,12 +59,6 @@ bin/test_connection
|
|
56
59
|
THINGS_AUTH_TOKEN=your_token_here bin/test_connection
|
57
60
|
```
|
58
61
|
|
59
|
-
3. **Via Rake:**
|
60
|
-
|
61
|
-
```bash
|
62
|
-
bundle exec rake test
|
63
|
-
```
|
64
|
-
|
65
62
|
The test script will:
|
66
63
|
|
67
64
|
- ✓ Check if Things app is running
|
@@ -71,7 +68,15 @@ The test script will:
|
|
71
68
|
- ✓ Verify the todo in the database
|
72
69
|
- ✓ Test update operations by completing the test todo (if auth token provided)
|
73
70
|
|
74
|
-
|
71
|
+
## Running the MCP Server
|
72
|
+
|
73
|
+
### If Using the Gem
|
74
|
+
|
75
|
+
```bash
|
76
|
+
things_mcp_server
|
77
|
+
```
|
78
|
+
|
79
|
+
### If Using from Source
|
75
80
|
|
76
81
|
```bash
|
77
82
|
bundle exec ruby bin/things_mcp_server
|
@@ -90,6 +95,20 @@ Add to your Claude Desktop configuration file:
|
|
90
95
|
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
91
96
|
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
92
97
|
|
98
|
+
#### Using the Released Gem (Recommended)
|
99
|
+
|
100
|
+
```json
|
101
|
+
{
|
102
|
+
"mcpServers": {
|
103
|
+
"things": {
|
104
|
+
"command": "things_mcp_server"
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}
|
108
|
+
```
|
109
|
+
|
110
|
+
#### Using from Source
|
111
|
+
|
93
112
|
```json
|
94
113
|
{
|
95
114
|
"mcpServers": {
|
@@ -116,6 +135,23 @@ For `update-todo` and `update-project` operations, you need to provide a Things
|
|
116
135
|
|
117
136
|
2. **Add the token to your configuration:**
|
118
137
|
|
138
|
+
#### Using the Released Gem
|
139
|
+
|
140
|
+
```json
|
141
|
+
{
|
142
|
+
"mcpServers": {
|
143
|
+
"things": {
|
144
|
+
"command": "things_mcp_server",
|
145
|
+
"env": {
|
146
|
+
"THINGS_AUTH_TOKEN": "your_authorization_token_here"
|
147
|
+
}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
151
|
+
```
|
152
|
+
|
153
|
+
#### Using from Source
|
154
|
+
|
119
155
|
```json
|
120
156
|
{
|
121
157
|
"mcpServers": {
|
@@ -131,6 +167,8 @@ For `update-todo` and `update-project` operations, you need to provide a Things
|
|
131
167
|
}
|
132
168
|
```
|
133
169
|
|
170
|
+
**Note:** Replace `YOUR_USERNAME` with your actual macOS username. If you have trouble finding the exact database path, you can run `find ~/Library/Group\ Containers -name "main.sqlite" 2>/dev/null | grep Things` to locate it.
|
171
|
+
|
134
172
|
⚠️ **Security Note:** Keep your authorization token private. It allows full access to modify your Things data.
|
135
173
|
|
136
174
|
### Other MCP Clients
|
@@ -193,15 +231,18 @@ Once configured, you can use your MCP-compatible AI client to:
|
|
193
231
|
- `add-project` - Create a new project in Things
|
194
232
|
- `update-todo` - Update an existing todo ⚠️ _Requires auth token_
|
195
233
|
- `update-project` - Update an existing project ⚠️ _Requires auth token_
|
234
|
+
|
235
|
+
> **Note:** When adding tags to existing todos/projects, the tags must already exist in Things. The URL scheme will not create new tags automatically.
|
236
|
+
|
196
237
|
- `show-item` - Show a specific item or list in Things
|
197
238
|
- `search-items` - Search for items and open in Things
|
198
239
|
|
199
240
|
## Development
|
200
241
|
|
201
|
-
Run tests:
|
242
|
+
Run connection tests:
|
202
243
|
|
203
244
|
```bash
|
204
|
-
|
245
|
+
bin/test_connection
|
205
246
|
```
|
206
247
|
|
207
248
|
Run linter:
|
@@ -210,12 +251,6 @@ Run linter:
|
|
210
251
|
bundle exec rake rubocop
|
211
252
|
```
|
212
253
|
|
213
|
-
Run both tests and linter:
|
214
|
-
|
215
|
-
```bash
|
216
|
-
bundle exec rake
|
217
|
-
```
|
218
|
-
|
219
254
|
## License
|
220
255
|
|
221
256
|
MIT
|
data/bin/test_connection
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
5
|
+
require "things_mcp"
|
6
6
|
|
7
7
|
puts "Testing Things MCP Ruby Server"
|
8
8
|
puts "=" * 40
|
@@ -71,7 +71,8 @@ begin
|
|
71
71
|
inbox_todos = ThingsMcp::Database.get_inbox
|
72
72
|
test_todo = inbox_todos.find { |t| t[:title] == test_todo_title }
|
73
73
|
break if test_todo
|
74
|
-
|
74
|
+
|
75
|
+
sleep(1) if i < 2 # Don't sleep after the last attempt
|
75
76
|
end
|
76
77
|
|
77
78
|
if test_todo
|
@@ -81,6 +82,7 @@ begin
|
|
81
82
|
"completed" => true,
|
82
83
|
})
|
83
84
|
|
85
|
+
# rubocop:disable Metrics/BlockNesting
|
84
86
|
if complete_result[:success]
|
85
87
|
puts "✅ Update operations working - test todo completed and cleaned up"
|
86
88
|
else
|
@@ -88,6 +90,7 @@ begin
|
|
88
90
|
puts " You may need to manually complete: '#{test_todo_title}'"
|
89
91
|
@test_failed = true
|
90
92
|
end
|
93
|
+
# rubocop:enable Metrics/BlockNesting
|
91
94
|
else
|
92
95
|
puts "❌ Could not find test todo in database after 3 attempts"
|
93
96
|
puts " Database sync delay longer than expected - please manually complete: '#{test_todo_title}'"
|
data/bin/things_mcp_server
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
lib = File.expand_path("../lib", __dir__)
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
+
require "things_mcp/server"
|
6
7
|
|
7
8
|
# Run the MCP server
|
8
9
|
ThingsMcp::Server.new.run
|
data/lib/things_mcp/database.rb
CHANGED
@@ -11,31 +11,7 @@ module ThingsMcp
|
|
11
11
|
# This class provides read-only access to the Things 3 database, enabling retrieval of todos, projects, areas, and
|
12
12
|
# tags. It handles dynamic database path resolution and provides formatted data structures.
|
13
13
|
class Database
|
14
|
-
|
15
14
|
class << self
|
16
|
-
def find_database_path
|
17
|
-
group_containers_dir = "#{Dir.home}/Library/Group Containers"
|
18
|
-
|
19
|
-
# Find Things-specific directories to avoid permission issues
|
20
|
-
things_dirs = Dir.glob("#{group_containers_dir}/*").select do |dir|
|
21
|
-
File.basename(dir).include?("culturedcode.ThingsMac")
|
22
|
-
end
|
23
|
-
|
24
|
-
things_dirs.each do |things_dir|
|
25
|
-
# Try new format first (Things 3.15.16+)
|
26
|
-
new_pattern = "#{things_dir}/ThingsData-*/Things Database.thingsdatabase/main.sqlite"
|
27
|
-
matches = Dir.glob(new_pattern)
|
28
|
-
return matches.first unless matches.empty?
|
29
|
-
|
30
|
-
# Fall back to old format
|
31
|
-
old_pattern = "#{things_dir}/Things Database.thingsdatabase/main.sqlite"
|
32
|
-
return old_pattern if File.exist?(old_pattern)
|
33
|
-
end
|
34
|
-
|
35
|
-
# Check environment variable
|
36
|
-
ENV["THINGSDB"] if ENV["THINGSDB"] && File.exist?(ENV["THINGSDB"])
|
37
|
-
end
|
38
|
-
|
39
15
|
def database_path
|
40
16
|
@database_path ||= find_database_path
|
41
17
|
end
|
@@ -47,15 +23,6 @@ module ThingsMcp
|
|
47
23
|
def with_database(&block)
|
48
24
|
db_path = database_path
|
49
25
|
unless db_path
|
50
|
-
$stderr.puts "DEBUG: Database path search failed"
|
51
|
-
$stderr.puts "DEBUG: Home directory: #{Dir.home}"
|
52
|
-
$stderr.puts "DEBUG: Group Containers exists: #{File.exist?("#{Dir.home}/Library/Group Containers")}"
|
53
|
-
if File.exist?("#{Dir.home}/Library/Group Containers")
|
54
|
-
containers = Dir.glob("#{Dir.home}/Library/Group Containers/*")
|
55
|
-
$stderr.puts "DEBUG: Found containers: #{containers.size}"
|
56
|
-
things_containers = containers.select { |c| File.basename(c).include?("culturedcode") }
|
57
|
-
$stderr.puts "DEBUG: Things containers: #{things_containers}"
|
58
|
-
end
|
59
26
|
raise "Things database not found. Please ensure Things 3 is installed and has been launched at least once."
|
60
27
|
end
|
61
28
|
|
@@ -335,9 +302,48 @@ module ThingsMcp
|
|
335
302
|
|
336
303
|
private
|
337
304
|
|
305
|
+
def find_database_path
|
306
|
+
# Use actual user's home directory, not the process owner's
|
307
|
+
actual_home = ENV["HOME"] || Dir.home
|
308
|
+
# If running as root, try to find the real user's home directory
|
309
|
+
if actual_home == "/var/root" && ENV["SUDO_USER"]
|
310
|
+
actual_home = "/Users/#{ENV["SUDO_USER"]}"
|
311
|
+
elsif actual_home == "/var/root"
|
312
|
+
# Fallback: look for the most recent user directory
|
313
|
+
user_dirs = Dir.glob("/Users/*").select { |d| File.directory?(d) && !File.basename(d).start_with?(".") }
|
314
|
+
actual_home = user_dirs.max_by { |d| File.mtime(d) } if user_dirs.any?
|
315
|
+
end
|
316
|
+
|
317
|
+
group_containers_dir = "#{actual_home}/Library/Group Containers"
|
318
|
+
|
319
|
+
# Find Things-specific directories to avoid permission issues
|
320
|
+
things_dirs = Dir.glob("#{group_containers_dir}/*").select do |dir|
|
321
|
+
File.basename(dir).include?("culturedcode.ThingsMac")
|
322
|
+
end
|
323
|
+
|
324
|
+
things_dirs.each do |things_dir|
|
325
|
+
# First try to find the current database (not in Backups folder)
|
326
|
+
current_pattern = "#{things_dir}/*/Things Database.thingsdatabase/main.sqlite"
|
327
|
+
current_matches = Dir.glob(current_pattern).reject { |path| path.include?("/Backups/") }
|
328
|
+
|
329
|
+
unless current_matches.empty?
|
330
|
+
return current_matches.first
|
331
|
+
end
|
332
|
+
|
333
|
+
# Fallback: look for any main.sqlite but exclude backups
|
334
|
+
fallback_pattern = "#{things_dir}/*/*/main.sqlite"
|
335
|
+
fallback_matches = Dir.glob(fallback_pattern).reject { |path| path.include?("/Backups/") }
|
336
|
+
|
337
|
+
unless fallback_matches.empty?
|
338
|
+
return fallback_matches.first
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
nil
|
343
|
+
end
|
344
|
+
|
338
345
|
def todo_columns
|
339
|
-
"uuid, title, notes, status, project, area, start, startDate, "
|
340
|
-
"deadline, creationDate, userModificationDate"
|
346
|
+
"uuid, title, notes, status, project, area, start, startDate, deadline, creationDate, userModificationDate"
|
341
347
|
end
|
342
348
|
|
343
349
|
def build_todo_query(project_uuid: nil)
|
data/lib/things_mcp/handlers.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "json"
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
require "things_mcp/database"
|
5
|
+
require "things_mcp/url_scheme"
|
6
|
+
require "things_mcp/formatters"
|
7
7
|
|
8
8
|
module ThingsMcp
|
9
9
|
# Tool call handlers for MCP server
|
@@ -206,8 +206,8 @@ module ThingsMcp
|
|
206
206
|
|
207
207
|
def handle_update_todo(args)
|
208
208
|
unless ENV["THINGS_AUTH_TOKEN"]
|
209
|
-
return "❌ Update operations require authentication. Please set THINGS_AUTH_TOKEN environment variable. "
|
210
|
-
|
209
|
+
return "❌ Update operations require authentication. Please set THINGS_AUTH_TOKEN environment variable. " \
|
210
|
+
"See README for setup instructions."
|
211
211
|
end
|
212
212
|
|
213
213
|
result = UrlScheme.update_todo(args)
|
@@ -221,8 +221,8 @@ module ThingsMcp
|
|
221
221
|
|
222
222
|
def handle_update_project(args)
|
223
223
|
unless ENV["THINGS_AUTH_TOKEN"]
|
224
|
-
return "❌ Update operations require authentication. Please set THINGS_AUTH_TOKEN environment variable. "
|
225
|
-
|
224
|
+
return "❌ Update operations require authentication. Please set THINGS_AUTH_TOKEN environment variable. " \
|
225
|
+
"See README for setup instructions."
|
226
226
|
end
|
227
227
|
|
228
228
|
result = UrlScheme.update_project(args)
|
data/lib/things_mcp/server.rb
CHANGED
@@ -3,10 +3,10 @@
|
|
3
3
|
require "mcp"
|
4
4
|
require "mcp/transports/stdio"
|
5
5
|
require "logger"
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
require "things_mcp/tools"
|
7
|
+
require "things_mcp/handlers"
|
8
|
+
require "things_mcp/database"
|
9
|
+
require "things_mcp/url_scheme"
|
10
10
|
|
11
11
|
module ThingsMcp
|
12
12
|
# MCP server implementation for Things 3 integration
|
@@ -27,7 +27,7 @@ module ThingsMcp
|
|
27
27
|
@server = MCP::Server.new(
|
28
28
|
name: "things",
|
29
29
|
version: "0.1.0",
|
30
|
-
tools: @tool_classes
|
30
|
+
tools: @tool_classes,
|
31
31
|
)
|
32
32
|
rescue => e
|
33
33
|
$stderr.puts "ERROR during initialization: #{e.class}: #{e.message}"
|
@@ -62,12 +62,12 @@ module ThingsMcp
|
|
62
62
|
def check_ruby_version
|
63
63
|
required_version = Gem::Version.new("3.2.0")
|
64
64
|
current_version = Gem::Version.new(RUBY_VERSION)
|
65
|
-
|
65
|
+
|
66
66
|
return if current_version >= required_version
|
67
67
|
|
68
68
|
$stderr.puts "❌ Ruby #{RUBY_VERSION} is too old! This server requires Ruby 3.2+"
|
69
69
|
$stderr.flush
|
70
|
-
exit
|
70
|
+
exit(1)
|
71
71
|
end
|
72
72
|
|
73
73
|
def create_tool_classes
|
@@ -107,12 +107,15 @@ module ThingsMcp
|
|
107
107
|
},
|
108
108
|
])
|
109
109
|
rescue => e
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
110
|
+
# Log the full error to stderr for debugging
|
111
|
+
$stderr.puts "ERROR in tool #{name}: #{e.class}: #{e.message}"
|
112
|
+
$stderr.puts "Arguments: #{string_arguments.inspect}"
|
113
|
+
$stderr.puts "Backtrace:"
|
114
|
+
e.backtrace.each { |line| $stderr.puts " #{line}" }
|
115
|
+
$stderr.flush
|
116
|
+
|
117
|
+
# Also raise the error so MCP can handle it properly
|
118
|
+
raise e
|
116
119
|
end
|
117
120
|
end
|
118
121
|
end
|
@@ -112,9 +112,8 @@ module ThingsMcp
|
|
112
112
|
# Build query string and convert + to %20 for spaces
|
113
113
|
query_string = URI.encode_www_form(params)
|
114
114
|
query_string = query_string.gsub("+", "%20") unless query_string.empty?
|
115
|
-
|
116
|
-
full_url = query_string.empty? ? base_url : "#{base_url}?#{query_string}"
|
117
115
|
|
116
|
+
full_url = query_string.empty? ? base_url : "#{base_url}?#{query_string}"
|
118
117
|
|
119
118
|
# Ensure Things is running
|
120
119
|
unless things_running?
|
@@ -151,6 +150,5 @@ module ThingsMcp
|
|
151
150
|
|
152
151
|
auth_required_operations.any? { |op| url.start_with?(op) }
|
153
152
|
end
|
154
|
-
|
155
153
|
end
|
156
154
|
end
|
data/lib/things_mcp.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "mcp"
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
require "things_mcp/server"
|
5
|
+
require "things_mcp/database"
|
6
|
+
require "things_mcp/handlers"
|
7
|
+
require "things_mcp/tools"
|
8
|
+
require "things_mcp/url_scheme"
|
9
|
+
require "things_mcp/formatters"
|
10
10
|
|
11
11
|
# ThingsMcp provides a Model Context Protocol (MCP) server for Things 3
|
12
12
|
#
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: things-mcp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hakan Ensari
|
@@ -10,52 +10,51 @@ cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
|
-
name:
|
13
|
+
name: logger
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
16
|
- - "~>"
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: '
|
18
|
+
version: '1.4'
|
19
19
|
type: :runtime
|
20
20
|
prerelease: false
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
22
22
|
requirements:
|
23
23
|
- - "~>"
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: '
|
25
|
+
version: '1.4'
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
|
-
name:
|
27
|
+
name: mcp
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
30
|
- - "~>"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '0.1'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
39
|
+
version: '0.1'
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
|
-
name:
|
41
|
+
name: sqlite3
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '2.0'
|
47
47
|
type: :runtime
|
48
48
|
prerelease: false
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '2.0'
|
54
54
|
description: A Model Context Protocol (MCP) server for Things 3, implemented in Ruby
|
55
55
|
email:
|
56
56
|
- hakanensari@gmail.com
|
57
57
|
executables:
|
58
|
-
- test_connection
|
59
58
|
- things_mcp_server
|
60
59
|
extensions: []
|
61
60
|
extra_rdoc_files: []
|
@@ -73,6 +72,7 @@ files:
|
|
73
72
|
- lib/things_mcp/server.rb
|
74
73
|
- lib/things_mcp/tools.rb
|
75
74
|
- lib/things_mcp/url_scheme.rb
|
75
|
+
- lib/things_mcp/version.rb
|
76
76
|
homepage: https://github.com/hakanensari/things-mcp-ruby
|
77
77
|
licenses:
|
78
78
|
- MIT
|