mcpeasy 0.1.0 → 0.2.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 +4 -4
- data/.claudeignore +0 -3
- data/.mcp.json +10 -1
- data/CHANGELOG.md +50 -0
- data/CLAUDE.md +19 -5
- data/README.md +19 -3
- data/lib/mcpeasy/cli.rb +33 -10
- data/lib/mcpeasy/config.rb +22 -1
- data/lib/mcpeasy/setup.rb +1 -0
- data/lib/mcpeasy/version.rb +1 -1
- data/lib/utilities/gcal/README.md +11 -3
- data/lib/utilities/gcal/cli.rb +110 -108
- data/lib/utilities/gcal/mcp.rb +463 -308
- data/lib/utilities/gcal/service.rb +312 -0
- data/lib/utilities/gdrive/README.md +3 -3
- data/lib/utilities/gdrive/cli.rb +98 -96
- data/lib/utilities/gdrive/mcp.rb +290 -288
- data/lib/utilities/gdrive/service.rb +293 -0
- data/lib/utilities/gmeet/cli.rb +131 -129
- data/lib/utilities/gmeet/mcp.rb +374 -372
- data/lib/utilities/gmeet/service.rb +409 -0
- data/lib/utilities/notion/README.md +287 -0
- data/lib/utilities/notion/cli.rb +245 -0
- data/lib/utilities/notion/mcp.rb +607 -0
- data/lib/utilities/notion/service.rb +327 -0
- data/lib/utilities/slack/README.md +3 -3
- data/lib/utilities/slack/cli.rb +69 -54
- data/lib/utilities/slack/mcp.rb +277 -226
- data/lib/utilities/slack/service.rb +134 -0
- metadata +11 -8
- data/env.template +0 -11
- data/lib/utilities/gcal/gcal_tool.rb +0 -308
- data/lib/utilities/gdrive/gdrive_tool.rb +0 -291
- data/lib/utilities/gmeet/gmeet_tool.rb +0 -407
- data/lib/utilities/slack/slack_tool.rb +0 -119
- data/logs/.keep +0 -0
data/lib/utilities/gcal/cli.rb
CHANGED
@@ -2,133 +2,135 @@
|
|
2
2
|
|
3
3
|
require "bundler/setup"
|
4
4
|
require "thor"
|
5
|
-
require_relative "
|
5
|
+
require_relative "service"
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
module Gcal
|
8
|
+
class CLI < Thor
|
9
|
+
desc "test", "Test the Google Calendar API connection"
|
10
|
+
def test
|
11
|
+
response = tool.test_connection
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
if response[:ok]
|
14
|
+
puts "✅ Successfully connected to Google Calendar"
|
15
|
+
puts " User: #{response[:user]} (#{response[:email]})"
|
16
|
+
else
|
17
|
+
warn "❌ Connection test failed"
|
18
|
+
end
|
19
|
+
rescue RuntimeError => e
|
20
|
+
puts "❌ Failed to connect to Google Calendar: #{e.message}\n\n#{e.backtrace.join("\n")}"
|
21
|
+
exit 1
|
17
22
|
end
|
18
|
-
rescue RuntimeError => e
|
19
|
-
puts "❌ Failed to connect to Google Calendar: #{e.message}\n\n#{e.backtrace.join("\n")}"
|
20
|
-
exit 1
|
21
|
-
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
24
|
+
desc "events", "List calendar events"
|
25
|
+
method_option :start_date, type: :string, aliases: "-s", desc: "Start date (YYYY-MM-DD)"
|
26
|
+
method_option :end_date, type: :string, aliases: "-e", desc: "End date (YYYY-MM-DD)"
|
27
|
+
method_option :max_results, type: :numeric, default: 20, aliases: "-n", desc: "Max number of events"
|
28
|
+
method_option :calendar_id, type: :string, aliases: "-c", desc: "Calendar ID (default: primary)"
|
29
|
+
def events
|
30
|
+
result = tool.list_events(
|
31
|
+
start_date: options[:start_date],
|
32
|
+
end_date: options[:end_date],
|
33
|
+
max_results: options[:max_results],
|
34
|
+
calendar_id: options[:calendar_id] || "primary"
|
35
|
+
)
|
36
|
+
events = result[:events]
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
38
|
+
if events.empty?
|
39
|
+
puts "📅 No events found for the specified date range"
|
40
|
+
else
|
41
|
+
puts "📅 Found #{result[:count]} event(s):"
|
42
|
+
events.each_with_index do |event, index|
|
43
|
+
puts " #{index + 1}. #{event[:summary] || "No title"}"
|
44
|
+
puts " Start: #{format_datetime(event[:start])}"
|
45
|
+
puts " End: #{format_datetime(event[:end])}"
|
46
|
+
puts " Description: #{event[:description]}" if event[:description]
|
47
|
+
puts " Location: #{event[:location]}" if event[:location]
|
48
|
+
puts " Attendees: #{event[:attendees].join(", ")}" if event[:attendees]&.any?
|
49
|
+
puts " Link: #{event[:html_link]}"
|
50
|
+
puts
|
51
|
+
end
|
50
52
|
end
|
53
|
+
rescue RuntimeError => e
|
54
|
+
warn "❌ Failed to list events: #{e.message}"
|
55
|
+
exit 1
|
51
56
|
end
|
52
|
-
rescue RuntimeError => e
|
53
|
-
warn "❌ Failed to list events: #{e.message}"
|
54
|
-
exit 1
|
55
|
-
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
desc "calendars", "List available calendars"
|
59
|
+
def calendars
|
60
|
+
result = tool.list_calendars
|
61
|
+
calendars = result[:calendars]
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
63
|
+
if calendars.empty?
|
64
|
+
puts "📋 No calendars found"
|
65
|
+
else
|
66
|
+
puts "📋 Found #{result[:count]} calendar(s):"
|
67
|
+
calendars.each_with_index do |calendar, index|
|
68
|
+
puts " #{index + 1}. #{calendar[:summary]}"
|
69
|
+
puts " ID: #{calendar[:id]}"
|
70
|
+
puts " Description: #{calendar[:description]}" if calendar[:description]
|
71
|
+
puts " Time Zone: #{calendar[:time_zone]}"
|
72
|
+
puts " Access Role: #{calendar[:access_role]}"
|
73
|
+
puts " Primary: Yes" if calendar[:primary]
|
74
|
+
puts
|
75
|
+
end
|
74
76
|
end
|
77
|
+
rescue RuntimeError => e
|
78
|
+
warn "❌ Failed to list calendars: #{e.message}"
|
79
|
+
exit 1
|
75
80
|
end
|
76
|
-
rescue RuntimeError => e
|
77
|
-
warn "❌ Failed to list calendars: #{e.message}"
|
78
|
-
exit 1
|
79
|
-
end
|
80
81
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
82
|
+
desc "search QUERY", "Search for events by text content"
|
83
|
+
method_option :start_date, type: :string, aliases: "-s", desc: "Start date (YYYY-MM-DD)"
|
84
|
+
method_option :end_date, type: :string, aliases: "-e", desc: "End date (YYYY-MM-DD)"
|
85
|
+
method_option :max_results, type: :numeric, default: 10, aliases: "-n", desc: "Max number of events"
|
86
|
+
def search(query)
|
87
|
+
result = tool.search_events(
|
88
|
+
query,
|
89
|
+
start_date: options[:start_date],
|
90
|
+
end_date: options[:end_date],
|
91
|
+
max_results: options[:max_results]
|
92
|
+
)
|
93
|
+
events = result[:events]
|
93
94
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
95
|
+
if events.empty?
|
96
|
+
puts "🔍 No events found matching '#{query}'"
|
97
|
+
else
|
98
|
+
puts "🔍 Found #{result[:count]} event(s) matching '#{query}':"
|
99
|
+
events.each_with_index do |event, index|
|
100
|
+
puts " #{index + 1}. #{event[:summary] || "No title"}"
|
101
|
+
puts " Start: #{format_datetime(event[:start])}"
|
102
|
+
puts " End: #{format_datetime(event[:end])}"
|
103
|
+
puts " Description: #{event[:description]}" if event[:description]
|
104
|
+
puts " Location: #{event[:location]}" if event[:location]
|
105
|
+
puts " Calendar: #{event[:calendar_id]}"
|
106
|
+
puts " Link: #{event[:html_link]}"
|
107
|
+
puts
|
108
|
+
end
|
107
109
|
end
|
110
|
+
rescue RuntimeError => e
|
111
|
+
warn "❌ Failed to search events: #{e.message}"
|
112
|
+
exit 1
|
108
113
|
end
|
109
|
-
rescue RuntimeError => e
|
110
|
-
warn "❌ Failed to search events: #{e.message}"
|
111
|
-
exit 1
|
112
|
-
end
|
113
114
|
|
114
|
-
|
115
|
+
private
|
115
116
|
|
116
|
-
|
117
|
-
|
118
|
-
|
117
|
+
def tool
|
118
|
+
@tool ||= Service.new
|
119
|
+
end
|
119
120
|
|
120
|
-
|
121
|
-
|
121
|
+
def format_datetime(datetime_info)
|
122
|
+
return "Unknown" unless datetime_info
|
122
123
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
124
|
+
if datetime_info[:date]
|
125
|
+
# All-day event
|
126
|
+
datetime_info[:date]
|
127
|
+
elsif datetime_info[:date_time]
|
128
|
+
# Specific time event
|
129
|
+
time = Time.parse(datetime_info[:date_time])
|
130
|
+
time.strftime("%Y-%m-%d %H:%M")
|
131
|
+
else
|
132
|
+
"Unknown"
|
133
|
+
end
|
132
134
|
end
|
133
135
|
end
|
134
136
|
end
|