mcpeasy 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: 5a8fd6efbce3698cb6ab7c807ee5b496f6f150108779991c4b2dac8d28822a64
4
+ data.tar.gz: 98e8f1895a741151767ca65243f3d83adc3feb37342624c35834bf2d0e4beeb4
5
+ SHA512:
6
+ metadata.gz: '07081dab8205a10e379933b40f9f618e7cb0ff05781f77b4ee7700c4a64b67f309346510d7677b813c09498a5172622ec8290294b4ffecdef5f6143a4777cac6'
7
+ data.tar.gz: 14e812027277e6035e6ab21cfb0730b35e1084c03b17ea2ca905a3654923da14fa2a8c183295904f913262a9a24e56078019384344387da7735523d8de148eb3
@@ -0,0 +1,15 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(bundle install:*)",
5
+ "Bash(bundle exec standardrb:*)",
6
+ "Bash(git status:*)",
7
+ "Bash(git diff:*)",
8
+ "Bash(git add:*)",
9
+ "Bash(git commit:*)",
10
+ "Bash(git push:*)",
11
+ "Bash(open https://meet.google.com/:*)"
12
+ ],
13
+ "deny": []
14
+ }
15
+ }
data/.claudeignore ADDED
@@ -0,0 +1,4 @@
1
+ .env
2
+ client_secret_*.apps.googleusercontent.com.json
3
+ google_credentials.json
4
+ .google-token.json
data/.envrc ADDED
@@ -0,0 +1,2 @@
1
+ # Load environment variables from .env file
2
+ dotenv
data/.mcp.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "mcpServers": {
3
+ "slack": {
4
+ "type": "stdio",
5
+ "command": "./bin/mcpz",
6
+ "args": [
7
+ "slack",
8
+ "mcp"
9
+ ],
10
+ "env": {}
11
+ },
12
+ "gdrive": {
13
+ "type": "stdio",
14
+ "command": "./bin/mcpz",
15
+ "args": [
16
+ "gdrive",
17
+ "mcp"
18
+ ],
19
+ "env": {}
20
+ },
21
+ "gcal": {
22
+ "type": "stdio",
23
+ "command": "./bin/mcpz",
24
+ "args": [
25
+ "gcal",
26
+ "mcp"
27
+ ],
28
+ "env": {}
29
+ },
30
+ "gmeet": {
31
+ "type": "stdio",
32
+ "command": "./bin/mcpz",
33
+ "args": [
34
+ "gmeet",
35
+ "mcp"
36
+ ],
37
+ "env": {}
38
+ }
39
+ }
40
+ }
data/CLAUDE.md ADDED
@@ -0,0 +1,170 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ **MCPEasy** is a Ruby gem that provides multiple Model Context Protocol (MCP) servers for integrating with AI assistants like Claude Code. The gem includes MCP servers for:
8
+
9
+ - **Slack** - Post messages and list channels
10
+ - **Google Calendar** - Access and search calendar events
11
+ - **Google Drive** - Search and retrieve files with automatic format conversion
12
+ - **Google Meet** - Find and manage Google Meet meetings
13
+
14
+ Each MCP server provides both CLI functionality and MCP server capabilities for AI assistant integration.
15
+
16
+ ## Dependencies and Setup
17
+
18
+ ### Development Setup
19
+
20
+ Install dependencies:
21
+ ```bash
22
+ bundle install
23
+ ```
24
+
25
+ ### Local Testing
26
+
27
+ Build and install the gem locally:
28
+ ```bash
29
+ gem build mcpeasy.gemspec
30
+ gem install mcpeasy-*.gem
31
+ ```
32
+
33
+ The gem is now available as the `mcpz` command system-wide.
34
+
35
+ ## Common Commands
36
+
37
+ ### Gem CLI Commands
38
+
39
+ ```bash
40
+ # Setup configuration directories
41
+ mcpz setup
42
+
43
+ # Check configuration status
44
+ mcpz config
45
+
46
+ # Set up authentication
47
+ mcpz google auth
48
+ mcpz slack set_bot_token xoxb-your-token
49
+
50
+ # Use individual services
51
+ mcpz slack post general "Hello world"
52
+ mcpz gcal events --start "2024-01-01"
53
+ mcpz gdrive search "quarterly report"
54
+ mcpz gmeet upcoming
55
+
56
+ # Run MCP servers
57
+ mcpz slack mcp
58
+ mcpz gcal mcp
59
+ mcpz gdrive mcp
60
+ mcpz gmeet mcp
61
+ ```
62
+
63
+ ### Development Commands
64
+
65
+ Run linting:
66
+ ```bash
67
+ bundle exec standardrb
68
+ ```
69
+
70
+ Build gem:
71
+ ```bash
72
+ gem build mcpeasy.gemspec
73
+ ```
74
+
75
+ ### MCP Server Configuration
76
+
77
+ For use with Claude Code, add to `.mcp.json`:
78
+ ```json
79
+ {
80
+ "mcpServers": {
81
+ "slack": {
82
+ "command": "mcpz",
83
+ "args": ["slack", "mcp"]
84
+ },
85
+ "gcal": {
86
+ "command": "mcpz",
87
+ "args": ["gcal", "mcp"]
88
+ },
89
+ "gdrive": {
90
+ "command": "mcpz",
91
+ "args": ["gdrive", "mcp"]
92
+ },
93
+ "gmeet": {
94
+ "command": "mcpz",
95
+ "args": ["gmeet", "mcp"]
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ## Code Quality
102
+
103
+ **IMPORTANT**: When editing Ruby source code, you MUST run `bundle exec standardrb` after making changes and fix any linting issues that are reported.
104
+
105
+ ## Architecture
106
+
107
+ ### Gem Structure
108
+ ```
109
+ lib/
110
+ ├── mcpeasy.rb # Main gem entry point
111
+ ├── mcpeasy/ # Core gem functionality
112
+ │ ├── version.rb # Gem version
113
+ │ ├── config.rb # Configuration management
114
+ │ └── cli.rb # Thor-based CLI interface
115
+ └── utilities/ # Individual MCP servers
116
+ ├── slack/ # Slack integration
117
+ ├── gcal/ # Google Calendar
118
+ ├── gdrive/ # Google Drive
119
+ └── gmeet/ # Google Meet
120
+ ```
121
+
122
+ ### Core Components
123
+
124
+ #### CLI (lib/mcpeasy/cli.rb)
125
+ - Thor-based command-line interface
126
+ - Subcommands for each service (slack, gcal, gdrive, gmeet)
127
+ - Configuration and setup commands
128
+ - Unified `mcpz` executable
129
+
130
+ #### Config (lib/mcpeasy/config.rb)
131
+ - Manages credentials and configuration
132
+ - Stores settings in `~/.config/mcpeasy/`
133
+ - Handles Google OAuth and Slack tokens
134
+
135
+ #### Individual MCP Servers
136
+ Each service directory follows a consistent structure with four key components:
137
+
138
+ ##### `cli.rb` - Service-specific CLI Commands
139
+ - Extends Thor for command-line interface functionality
140
+ - Provides user-friendly CLI commands for the service
141
+ - Handles argument parsing and validation
142
+ - Calls into the `*_tool.rb` for actual service operations
143
+ - Example: `mcpz slack post` command implementation
144
+
145
+ ##### `mcp.rb` - MCP Server Implementation
146
+ - Implements the Model Context Protocol JSON-RPC server
147
+ - Handles MCP initialization, tool registration, and request processing
148
+ - Translates MCP tool calls into `*_tool.rb` method calls
149
+ - Provides structured responses back to AI assistants
150
+ - Runs as a persistent server process when called with `mcpz [service] mcp`
151
+
152
+ ##### `*_tool.rb` - Core Service Functionality
153
+ - Contains the main business logic for interacting with external APIs
154
+ - Handles authentication, API calls, error handling, and response formatting
155
+ - Shared between both CLI and MCP modes for consistency
156
+ - Service-specific naming: `slack_tool.rb`, `gcal_tool.rb`, `gdrive_tool.rb`, `gmeet_tool.rb`
157
+ - Designed to be framework-agnostic and reusable
158
+
159
+ ##### `README.md` - Service-specific Documentation
160
+ - Detailed setup instructions for the specific service
161
+ - API credential configuration steps
162
+ - CLI usage examples and MCP server configuration
163
+ - Service-specific features and limitations
164
+ - Troubleshooting guides
165
+
166
+ ### Execution Patterns
167
+ All services follow the same pattern:
168
+ 1. **CLI mode**: Direct command-line usage via `mcpz [service] [command]`
169
+ 2. **MCP mode**: JSON-RPC server mode via `mcpz [service] mcp`
170
+ 3. **Authentication**: Service-specific auth handling with shared config storage
data/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # MCPEasy
2
+
3
+ A Ruby gem that provides multiple Model Context Protocol (MCP) servers for integrating with AI assistants like Claude Code. Each MCP server provides programmatic access to popular web services and APIs.
4
+
5
+ ## Installation
6
+
7
+ Install the gem globally:
8
+
9
+ ```bash
10
+ gem install mcpeasy
11
+ ```
12
+
13
+ This makes the `mcpz` command available system-wide for both CLI usage and MCP server configuration.
14
+
15
+ ## Available MCP Servers
16
+
17
+ This gem includes the following MCP servers, each providing both CLI and MCP server functionality:
18
+
19
+ ### 🗣️ [Slack](./lib/utilities/slack/)
20
+ Post messages to Slack channels and list available channels.
21
+ - CLI: Direct message posting with custom usernames
22
+ - MCP: Integration for AI assistants to send Slack notifications
23
+
24
+ ### 📅 [Google Calendar](./lib/utilities/gcal/)
25
+ Access and search Google Calendar events.
26
+ - CLI: List events, search by date range, view calendar information
27
+ - MCP: AI assistant access to calendar data and event search
28
+
29
+ ### 📂 [Google Drive](./lib/utilities/gdrive/)
30
+ Search and retrieve files from Google Drive with automatic format conversion.
31
+ - CLI: Search files, list recent files, retrieve content
32
+ - MCP: AI assistant access to Drive files and documents
33
+
34
+ ### 🎥 [Google Meet](./lib/utilities/gmeet/)
35
+ Find and manage Google Meet meetings from your calendar.
36
+ - CLI: List meetings, search by content, get meeting URLs
37
+ - MCP: AI assistant access to upcoming meetings and direct links
38
+
39
+ ## Quick Start
40
+
41
+ ### 1. Configuration Setup
42
+
43
+ First, create the configuration directories:
44
+
45
+ ```bash
46
+ mcpz setup
47
+ ```
48
+
49
+ Then configure your API credentials for each service you plan to use:
50
+
51
+ ```bash
52
+ # For Slack
53
+ mcpz slack set_bot_token xoxb-your-slack-token
54
+
55
+ # For Google services (Calendar, Drive, Meet)
56
+ mcpz google auth
57
+ ```
58
+
59
+ Credentials are stored securely in `~/.config/mcpeasy/` (see individual server documentation for specific setup requirements).
60
+
61
+ ### 2. CLI Usage
62
+
63
+ Each MCP server can be used directly from the command line:
64
+
65
+ ```bash
66
+ # Slack
67
+ mcpz slack post general "Hello from Ruby!"
68
+
69
+ # Google Calendar
70
+ mcpz gcal events --start "2024-01-01"
71
+
72
+ # Google Drive
73
+ mcpz gdrive search "quarterly report"
74
+
75
+ # Google Meet
76
+ mcpz gmeet upcoming
77
+ ```
78
+
79
+ ### 3. MCP Server Configuration
80
+
81
+ For use with Claude Code, add servers to your `.mcp.json`:
82
+
83
+ ```json
84
+ {
85
+ "mcpServers": {
86
+ "slack": {
87
+ "command": "mcpz",
88
+ "args": ["slack", "mcp"]
89
+ },
90
+ "gcal": {
91
+ "command": "mcpz",
92
+ "args": ["gcal", "mcp"]
93
+ },
94
+ "gdrive": {
95
+ "command": "mcpz",
96
+ "args": ["gdrive", "mcp"]
97
+ },
98
+ "gmeet": {
99
+ "command": "mcpz",
100
+ "args": ["gmeet", "mcp"]
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ ## Development
107
+
108
+ ### Setup
109
+
110
+ 1. Clone the repository and install dependencies:
111
+ ```bash
112
+ git clone <repository-url>
113
+ cd mcpeasy
114
+ bundle install
115
+ ```
116
+
117
+ 2. Create configuration directories (if not automatically created):
118
+ ```bash
119
+ # Run manually during development
120
+ bundle exec ruby -r "./lib/mcpeasy/setup" -e "Mcpeasy::Setup.create_config_directories"
121
+
122
+ # Or use the CLI command after building the gem locally
123
+ bin/mcpz setup
124
+ ```
125
+
126
+ ### Code Quality
127
+
128
+ Run linting before committing changes:
129
+
130
+ ```bash
131
+ bundle exec standardrb
132
+ ```
133
+
134
+ ### Project Structure
135
+
136
+ ```
137
+ lib/
138
+ ├── mcpeasy.rb # Main gem file
139
+ ├── mcpeasy/ # Gem core functionality
140
+ └── utilities/ # MCP servers
141
+ ├── slack/ # Slack integration
142
+ ├── gcal/ # Google Calendar
143
+ ├── gdrive/ # Google Drive
144
+ └── gmeet/ # Google Meet
145
+ ```
146
+
147
+ ### Contributing
148
+
149
+ 1. Follow existing code patterns and Ruby style conventions
150
+ 2. Add comprehensive error handling and logging
151
+ 3. Update relevant documentation for new features
152
+ 4. Test both CLI and MCP server modes
153
+ 5. Run `bundle exec standardrb` before submitting changes
154
+
155
+ ## License
156
+
157
+ This project is licensed under the MIT License.
158
+
159
+ ## Support
160
+
161
+ For issues, questions, or contributions, please visit the project repository.
data/bin/mcpz ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../lib/mcpeasy"
5
+
6
+ Mcpeasy::CLI.start(ARGV)
data/env.template ADDED
@@ -0,0 +1,11 @@
1
+ # Copy this file to .env and replace the placeholders with your own values
2
+
3
+ # Used by the slack_poster.rb script
4
+ SLACK_BOT_TOKEN=xoxb-REPLACE-ME
5
+
6
+ # Used by the Github MCP Server
7
+ GITHUB_PERSONAL_ACCESS_TOKEN=github_pat_REPLACE_ME
8
+
9
+ # Used by the Google Drive MCP Server
10
+ GOOGLE_CLIENT_ID=your_client_id_here.apps.googleusercontent.com
11
+ GOOGLE_CLIENT_SECRET=your_client_secret_here
data/ext/setup.rb ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../lib/mcpeasy/setup"
5
+
6
+ # This script runs during gem installation
7
+ Mcpeasy::Setup.create_config_directories
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+ require_relative "config"
5
+
6
+ module Mcpeasy
7
+ class GoogleCommands < Thor
8
+ desc "auth", "Authenticate with Google services (Calendar, Drive, Meet)"
9
+ def auth
10
+ require_relative "../utilities/gcal/gcal_tool"
11
+ tool = GcalTool.new(skip_auth: true)
12
+ result = tool.authenticate
13
+ if result[:success]
14
+ puts "✅ Successfully authenticated with Google services"
15
+ puts " This enables access to Calendar, Drive, and Meet"
16
+ else
17
+ puts "❌ Authentication failed: #{result[:error]}"
18
+ exit 1
19
+ end
20
+ end
21
+ end
22
+
23
+ # Load the existing GcalCLI and extend it with MCP functionality
24
+ require_relative "../utilities/gcal/cli"
25
+
26
+ class GcalCommands < GcalCLI
27
+ namespace "gcal"
28
+
29
+ desc "mcp", "Run Google Calendar MCP server"
30
+ def mcp
31
+ require_relative "../utilities/gcal/mcp"
32
+ MCPServer.new.run
33
+ end
34
+ end
35
+
36
+ # Load the existing GdriveCLI and extend it with MCP functionality
37
+ require_relative "../utilities/gdrive/cli"
38
+
39
+ class GdriveCommands < GdriveCLI
40
+ namespace "gdrive"
41
+
42
+ desc "mcp", "Run Google Drive MCP server"
43
+ def mcp
44
+ require_relative "../utilities/gdrive/mcp"
45
+ MCPServer.new.run
46
+ end
47
+ end
48
+
49
+ # Load the existing GmeetCLI and extend it with MCP functionality
50
+ require_relative "../utilities/gmeet/cli"
51
+
52
+ class GmeetCommands < GmeetCLI
53
+ namespace "gmeet"
54
+
55
+ desc "mcp", "Run Google Meet MCP server"
56
+ def mcp
57
+ require_relative "../utilities/gmeet/mcp"
58
+ MCPServer.new.run
59
+ end
60
+ end
61
+
62
+ # Load the existing SlackCLI and extend it with MCP functionality
63
+ require_relative "../utilities/slack/cli"
64
+
65
+ class SlackCommands < SlackCLI
66
+ namespace "slack"
67
+
68
+ desc "mcp", "Run Slack MCP server"
69
+ def mcp
70
+ require_relative "../utilities/slack/mcp"
71
+ MCPServer.new.run
72
+ end
73
+
74
+ desc "set_bot_token TOKEN", "Set Slack bot token"
75
+ def set_bot_token(token)
76
+ Config.save_slack_bot_token(token)
77
+ puts "✅ Slack bot token saved successfully"
78
+ end
79
+
80
+ # Alias the inherited 'list' command as 'channels' for consistency
81
+ desc "channels", "List Slack channels"
82
+ def channels
83
+ list
84
+ end
85
+ end
86
+
87
+ class CLI < Thor
88
+ desc "version", "Show mcpeasy version"
89
+ def version
90
+ puts "mcpeasy #{Mcpeasy::VERSION}"
91
+ puts "mcpeasy, LM squeezy! 🤖"
92
+ end
93
+
94
+ desc "setup", "Create configuration directories"
95
+ def setup
96
+ require_relative "setup"
97
+ Setup.create_config_directories
98
+ end
99
+
100
+ desc "config", "Show configuration status"
101
+ def config
102
+ status = Config.config_status
103
+ puts "📁 Config directory: #{status[:config_dir]}"
104
+ puts "📄 Logs directory: #{status[:logs_dir]}"
105
+ puts "🔑 Google credentials: #{status[:google_credentials] ? "✅" : "❌"}"
106
+ puts "🎫 Google token: #{status[:google_token] ? "✅" : "❌"}"
107
+ puts "💬 Slack config: #{status[:slack_config] ? "✅" : "❌"}"
108
+ end
109
+
110
+ desc "set_google_credentials PATH", "Save Google credentials from downloaded JSON file"
111
+ def set_google_credentials(path)
112
+ unless File.exist?(path)
113
+ puts "❌ File not found: #{path}"
114
+ exit 1
115
+ end
116
+
117
+ begin
118
+ credentials_json = File.read(path)
119
+ JSON.parse(credentials_json) # Validate it's valid JSON
120
+ Config.save_google_credentials(credentials_json)
121
+ puts "✅ Google credentials saved successfully"
122
+ rescue JSON::ParserError
123
+ puts "❌ Invalid JSON file"
124
+ exit 1
125
+ rescue => e
126
+ puts "❌ Error saving credentials: #{e.message}"
127
+ exit 1
128
+ end
129
+ end
130
+
131
+ desc "google COMMAND", "Google services authentication"
132
+ subcommand "google", GoogleCommands
133
+
134
+ desc "gcal COMMAND", "Google Calendar commands"
135
+ subcommand "gcal", GcalCommands
136
+
137
+ desc "gdrive COMMAND", "Google Drive commands"
138
+ subcommand "gdrive", GdriveCommands
139
+
140
+ desc "gmeet COMMAND", "Google Meet commands"
141
+ subcommand "gmeet", GmeetCommands
142
+
143
+ desc "slack COMMAND", "Slack commands"
144
+ subcommand "slack", SlackCommands
145
+
146
+ class << self
147
+ private
148
+
149
+ def exit_on_failure?
150
+ true
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "json"
5
+ require "mother"
6
+
7
+ module Mcpeasy
8
+ class Config
9
+ CONFIG_DIR = File.expand_path("~/.config/mcpeasy").freeze
10
+ GOOGLE_DIR = File.join(CONFIG_DIR, "google").freeze
11
+ SLACK_DIR = File.join(CONFIG_DIR, "slack").freeze
12
+ LOGS_DIR = File.expand_path("~/.local/share/mcpeasy/logs").freeze
13
+
14
+ class << self
15
+ def ensure_config_dirs
16
+ FileUtils.mkdir_p(CONFIG_DIR)
17
+ FileUtils.mkdir_p(GOOGLE_DIR)
18
+ FileUtils.mkdir_p(SLACK_DIR)
19
+ FileUtils.mkdir_p(LOGS_DIR)
20
+ end
21
+
22
+ # Google credentials management
23
+ def google_credentials_path
24
+ File.join(GOOGLE_DIR, "credentials.json")
25
+ end
26
+
27
+ def google_credentials
28
+ return nil unless File.exist?(google_credentials_path)
29
+ Mother.create(google_credentials_path)
30
+ end
31
+
32
+ def save_google_credentials(credentials_json)
33
+ ensure_config_dirs
34
+ File.write(google_credentials_path, credentials_json)
35
+ end
36
+
37
+ def google_client_id
38
+ credentials = google_credentials
39
+ return nil unless credentials
40
+ credentials.installed&.client_id || credentials.web&.client_id
41
+ end
42
+
43
+ def google_client_secret
44
+ credentials = google_credentials
45
+ return nil unless credentials
46
+ credentials.installed&.client_secret || credentials.web&.client_secret
47
+ end
48
+
49
+ # Google token management
50
+ def google_token_path
51
+ File.join(GOOGLE_DIR, "token.json")
52
+ end
53
+
54
+ def google_token
55
+ return nil unless File.exist?(google_token_path)
56
+ Mother.create(google_token_path)
57
+ end
58
+
59
+ def save_google_token(token_data)
60
+ ensure_config_dirs
61
+ File.write(google_token_path, JSON.pretty_generate(token_data))
62
+ end
63
+
64
+ # Slack configuration
65
+ def slack_token_path
66
+ File.join(SLACK_DIR, "token.json")
67
+ end
68
+
69
+ def slack_bot_token
70
+ return nil unless File.exist?(slack_token_path)
71
+ config = JSON.parse(File.read(slack_token_path))
72
+ config["bot_token"]
73
+ end
74
+
75
+ def save_slack_bot_token(token)
76
+ ensure_config_dirs
77
+ config = File.exist?(slack_token_path) ? JSON.parse(File.read(slack_token_path)) : {}
78
+ config["bot_token"] = token
79
+ File.write(slack_token_path, JSON.pretty_generate(config))
80
+ end
81
+
82
+ # Logs directory
83
+ def logs_dir
84
+ LOGS_DIR
85
+ end
86
+
87
+ def log_file_path(service, type = "error")
88
+ File.join(LOGS_DIR, "mcp_#{service}_#{type}.log")
89
+ end
90
+
91
+ def config_status
92
+ {
93
+ config_dir: CONFIG_DIR,
94
+ logs_dir: LOGS_DIR,
95
+ google_credentials: File.exist?(google_credentials_path),
96
+ google_token: File.exist?(google_token_path),
97
+ slack_config: File.exist?(slack_token_path)
98
+ }
99
+ end
100
+ end
101
+ end
102
+ end