mcpeasy 0.1.0 → 0.3.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 +19 -1
- data/CHANGELOG.md +59 -0
- data/CLAUDE.md +19 -5
- data/README.md +19 -3
- data/lib/mcpeasy/cli.rb +62 -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/gmail/README.md +278 -0
- data/lib/utilities/gmail/cli.rb +264 -0
- data/lib/utilities/gmail/mcp.rb +846 -0
- data/lib/utilities/gmail/service.rb +547 -0
- data/lib/utilities/gmeet/cli.rb +131 -129
- data/lib/utilities/gmeet/mcp.rb +374 -372
- data/lib/utilities/gmeet/service.rb +411 -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
- data/mcpeasy.gemspec +6 -1
- metadata +87 -10
- 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/gmeet/cli.rb
CHANGED
@@ -2,156 +2,158 @@
|
|
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 Gmeet
|
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}"
|
21
|
+
exit 1
|
17
22
|
end
|
18
|
-
rescue RuntimeError => e
|
19
|
-
puts "❌ Failed to connect to Google Calendar: #{e.message}"
|
20
|
-
exit 1
|
21
|
-
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
24
|
+
desc "meetings", "List Google Meet meetings"
|
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 meetings"
|
28
|
+
method_option :calendar_id, type: :string, aliases: "-c", desc: "Calendar ID (default: primary)"
|
29
|
+
def meetings
|
30
|
+
result = tool.list_meetings(
|
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
|
+
meetings = result[:meetings]
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
38
|
+
if meetings.empty?
|
39
|
+
puts "🎥 No Google Meet meetings found for the specified date range"
|
40
|
+
else
|
41
|
+
puts "🎥 Found #{result[:count]} Google Meet meeting(s):"
|
42
|
+
meetings.each_with_index do |meeting, index|
|
43
|
+
puts " #{index + 1}. #{meeting[:summary] || "No title"}"
|
44
|
+
puts " Start: #{format_datetime(meeting[:start])}"
|
45
|
+
puts " End: #{format_datetime(meeting[:end])}"
|
46
|
+
puts " Description: #{meeting[:description]}" if meeting[:description]
|
47
|
+
puts " Location: #{meeting[:location]}" if meeting[:location]
|
48
|
+
puts " Attendees: #{meeting[:attendees].join(", ")}" if meeting[:attendees]&.any?
|
49
|
+
puts " Meet Link: #{meeting[:meet_link]}"
|
50
|
+
puts " Calendar Link: #{meeting[:html_link]}"
|
51
|
+
puts
|
52
|
+
end
|
51
53
|
end
|
54
|
+
rescue RuntimeError => e
|
55
|
+
warn "❌ Failed to list meetings: #{e.message}"
|
56
|
+
exit 1
|
52
57
|
end
|
53
|
-
rescue RuntimeError => e
|
54
|
-
warn "❌ Failed to list meetings: #{e.message}"
|
55
|
-
exit 1
|
56
|
-
end
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
59
|
+
desc "upcoming", "List upcoming Google Meet meetings"
|
60
|
+
method_option :max_results, type: :numeric, default: 10, aliases: "-n", desc: "Max number of meetings"
|
61
|
+
method_option :calendar_id, type: :string, aliases: "-c", desc: "Calendar ID (default: primary)"
|
62
|
+
def upcoming
|
63
|
+
result = tool.upcoming_meetings(
|
64
|
+
max_results: options[:max_results],
|
65
|
+
calendar_id: options[:calendar_id] || "primary"
|
66
|
+
)
|
67
|
+
meetings = result[:meetings]
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
69
|
+
if meetings.empty?
|
70
|
+
puts "🎥 No upcoming Google Meet meetings found in the next 24 hours"
|
71
|
+
else
|
72
|
+
puts "🎥 Found #{result[:count]} upcoming Google Meet meeting(s):"
|
73
|
+
meetings.each_with_index do |meeting, index|
|
74
|
+
puts " #{index + 1}. #{meeting[:summary] || "No title"}"
|
75
|
+
puts " Start: #{format_datetime(meeting[:start])} (#{meeting[:time_until_start]})"
|
76
|
+
puts " End: #{format_datetime(meeting[:end])}"
|
77
|
+
puts " Description: #{meeting[:description]}" if meeting[:description]
|
78
|
+
puts " Location: #{meeting[:location]}" if meeting[:location]
|
79
|
+
puts " Attendees: #{meeting[:attendees].join(", ")}" if meeting[:attendees]&.any?
|
80
|
+
puts " Meet Link: #{meeting[:meet_link]}"
|
81
|
+
puts " Calendar Link: #{meeting[:html_link]}"
|
82
|
+
puts
|
83
|
+
end
|
82
84
|
end
|
85
|
+
rescue RuntimeError => e
|
86
|
+
warn "❌ Failed to list upcoming meetings: #{e.message}"
|
87
|
+
exit 1
|
83
88
|
end
|
84
|
-
rescue RuntimeError => e
|
85
|
-
warn "❌ Failed to list upcoming meetings: #{e.message}"
|
86
|
-
exit 1
|
87
|
-
end
|
88
89
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
90
|
+
desc "search QUERY", "Search for Google Meet meetings by text content"
|
91
|
+
method_option :start_date, type: :string, aliases: "-s", desc: "Start date (YYYY-MM-DD)"
|
92
|
+
method_option :end_date, type: :string, aliases: "-e", desc: "End date (YYYY-MM-DD)"
|
93
|
+
method_option :max_results, type: :numeric, default: 10, aliases: "-n", desc: "Max number of meetings"
|
94
|
+
def search(query)
|
95
|
+
result = tool.search_meetings(
|
96
|
+
query,
|
97
|
+
start_date: options[:start_date],
|
98
|
+
end_date: options[:end_date],
|
99
|
+
max_results: options[:max_results]
|
100
|
+
)
|
101
|
+
meetings = result[:meetings]
|
101
102
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
103
|
+
if meetings.empty?
|
104
|
+
puts "🔍 No Google Meet meetings found matching '#{query}'"
|
105
|
+
else
|
106
|
+
puts "🔍 Found #{result[:count]} Google Meet meeting(s) matching '#{query}':"
|
107
|
+
meetings.each_with_index do |meeting, index|
|
108
|
+
puts " #{index + 1}. #{meeting[:summary] || "No title"}"
|
109
|
+
puts " Start: #{format_datetime(meeting[:start])}"
|
110
|
+
puts " End: #{format_datetime(meeting[:end])}"
|
111
|
+
puts " Description: #{meeting[:description]}" if meeting[:description]
|
112
|
+
puts " Location: #{meeting[:location]}" if meeting[:location]
|
113
|
+
puts " Meet Link: #{meeting[:meet_link]}"
|
114
|
+
puts " Calendar Link: #{meeting[:html_link]}"
|
115
|
+
puts
|
116
|
+
end
|
115
117
|
end
|
118
|
+
rescue RuntimeError => e
|
119
|
+
warn "❌ Failed to search meetings: #{e.message}"
|
120
|
+
exit 1
|
116
121
|
end
|
117
|
-
rescue RuntimeError => e
|
118
|
-
warn "❌ Failed to search meetings: #{e.message}"
|
119
|
-
exit 1
|
120
|
-
end
|
121
122
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
123
|
+
desc "url EVENT_ID", "Get the Google Meet URL for a specific event"
|
124
|
+
method_option :calendar_id, type: :string, aliases: "-c", desc: "Calendar ID (default: primary)"
|
125
|
+
def url(event_id)
|
126
|
+
result = tool.get_meeting_url(event_id, calendar_id: options[:calendar_id] || "primary")
|
126
127
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
128
|
+
puts "🎥 #{result[:summary] || "Meeting"}"
|
129
|
+
puts " Start: #{format_datetime(result[:start])}"
|
130
|
+
puts " End: #{format_datetime(result[:end])}"
|
131
|
+
puts " Meet Link: #{result[:meet_link]}"
|
132
|
+
puts " Event ID: #{result[:event_id]}"
|
133
|
+
rescue RuntimeError => e
|
134
|
+
warn "❌ Failed to get meeting URL: #{e.message}"
|
135
|
+
exit 1
|
136
|
+
end
|
136
137
|
|
137
|
-
|
138
|
+
private
|
138
139
|
|
139
|
-
|
140
|
-
|
141
|
-
|
140
|
+
def tool
|
141
|
+
@tool ||= Service.new
|
142
|
+
end
|
142
143
|
|
143
|
-
|
144
|
-
|
144
|
+
def format_datetime(datetime_info)
|
145
|
+
return "Unknown" unless datetime_info
|
145
146
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
147
|
+
if datetime_info[:date]
|
148
|
+
# All-day event
|
149
|
+
datetime_info[:date]
|
150
|
+
elsif datetime_info[:date_time]
|
151
|
+
# Specific time event
|
152
|
+
time = Time.parse(datetime_info[:date_time])
|
153
|
+
time.strftime("%Y-%m-%d %H:%M")
|
154
|
+
else
|
155
|
+
"Unknown"
|
156
|
+
end
|
155
157
|
end
|
156
158
|
end
|
157
159
|
end
|