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