Skip to content

Commit fcda14a

Browse files
committed
check if r packages are installed or not
1 parent c94fc06 commit fcda14a

3 files changed

Lines changed: 188 additions & 5 deletions

File tree

README.md

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ pip install rmcp
1616
```
1717

1818
```bash
19+
# Check R packages are installed
20+
rmcp check-r-packages
21+
1922
# Start the MCP server
2023
rmcp start
2124
```
@@ -122,8 +125,42 @@ RMCP has been tested with real-world scenarios achieving **100% success rate**:
122125
## 🔧 Installation & Setup
123126

124127
### Prerequisites
125-
- Python 3.8+
126-
- R 4.0+ (automatically configured)
128+
- **Python 3.8+**
129+
- **R 4.0+** with required packages (see below)
130+
131+
#### R Package Requirements
132+
133+
RMCP requires the following R packages. Install all at once with:
134+
135+
```r
136+
# Install all required packages (recommended)
137+
install.packages(c(
138+
# Core statistical packages
139+
"jsonlite", "plm", "lmtest", "sandwich", "AER", "dplyr",
140+
# Time series analysis
141+
"forecast", "vars", "urca", "tseries",
142+
# Statistical testing
143+
"nortest", "car",
144+
# Machine learning
145+
"rpart", "randomForest",
146+
# Data visualization
147+
"ggplot2", "gridExtra", "tidyr", "rlang"
148+
), repos = "https://cran.rstudio.com/")
149+
```
150+
151+
**Minimum Core Packages** (basic functionality only):
152+
```r
153+
install.packages(c("jsonlite", "plm", "lmtest", "sandwich", "AER"))
154+
```
155+
156+
**Feature-Specific Packages:**
157+
- **Time Series Analysis**: `forecast`, `vars`, `urca`, `tseries`
158+
- **Machine Learning**: `rpart`, `randomForest`
159+
- **Data Visualization**: `ggplot2`, `gridExtra`, `tidyr`, `rlang`
160+
- **Statistical Testing**: `nortest`, `car`
161+
- **Data Manipulation**: `dplyr`
162+
163+
💡 **Tip**: Install all packages first to avoid errors. Missing packages will cause specific tools to fail with clear error messages.
127164

128165
### Install via pip
129166
```bash
@@ -442,11 +479,30 @@ sudo apt-get install r-base
442479
```
443480

444481
**Missing R packages:**
482+
483+
First, check which packages are missing:
484+
```bash
485+
rmcp check-r-packages
486+
```
487+
488+
Then install missing packages in R:
445489
```r
446-
# In R console, install required packages
490+
# Install all RMCP packages (recommended)
491+
install.packages(c(
492+
"jsonlite", "plm", "lmtest", "sandwich", "AER", "dplyr",
493+
"forecast", "vars", "urca", "tseries", "nortest", "car",
494+
"rpart", "randomForest", "ggplot2", "gridExtra", "tidyr", "rlang"
495+
), repos = "https://cran.rstudio.com/")
496+
497+
# Or install just core packages (limited functionality)
447498
install.packages(c("jsonlite", "plm", "lmtest", "sandwich", "AER"))
448499
```
449500

501+
**Package installation fails:**
502+
- On Ubuntu/Debian: `sudo apt-get install r-base-dev libcurl4-openssl-dev libssl-dev libxml2-dev`
503+
- On macOS with Homebrew: `brew install r`
504+
- On Windows: Download from [CRAN](https://cran.r-project.org/bin/windows/base/)
505+
450506
**MCP connection issues:**
451507
```bash
452508
# Test server directly

rmcp/cli.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,86 @@ def validate_config():
239239
# TODO: Add config validation
240240

241241

242+
@cli.command("check-r-packages")
243+
def check_r_packages():
244+
"""Check R package installation status."""
245+
import subprocess
246+
import json
247+
248+
# Define all required packages with their categories
249+
packages = {
250+
"Core Statistical": ["jsonlite", "plm", "lmtest", "sandwich", "AER", "dplyr"],
251+
"Time Series": ["forecast", "vars", "urca", "tseries"],
252+
"Statistical Testing": ["nortest", "car"],
253+
"Machine Learning": ["rpart", "randomForest"],
254+
"Data Visualization": ["ggplot2", "gridExtra", "tidyr", "rlang"]
255+
}
256+
257+
click.echo("🔍 Checking R Package Installation Status")
258+
click.echo("=" * 50)
259+
260+
# Check if R is available
261+
try:
262+
result = subprocess.run(['R', '--version'], capture_output=True, text=True, timeout=10)
263+
if result.returncode != 0:
264+
click.echo("❌ R not found. Please install R first.")
265+
return
266+
version_line = result.stdout.split('\n')[0]
267+
click.echo(f"✅ R is available: {version_line}")
268+
except Exception as e:
269+
click.echo(f"❌ R check failed: {e}")
270+
return
271+
272+
click.echo()
273+
274+
# Check each package category
275+
all_packages = []
276+
missing_packages = []
277+
278+
for category, pkg_list in packages.items():
279+
click.echo(f"📦 {category} Packages:")
280+
for pkg in pkg_list:
281+
all_packages.append(pkg)
282+
try:
283+
# Check if package is installed
284+
r_cmd = f'if (require("{pkg}", quietly=TRUE)) cat("INSTALLED") else cat("MISSING")'
285+
result = subprocess.run(['R', '--slave', '-e', r_cmd],
286+
capture_output=True, text=True, timeout=10)
287+
if "INSTALLED" in result.stdout:
288+
click.echo(f" ✅ {pkg}")
289+
else:
290+
click.echo(f" ❌ {pkg}")
291+
missing_packages.append(pkg)
292+
except Exception:
293+
click.echo(f" ❓ {pkg} (check failed)")
294+
missing_packages.append(pkg)
295+
click.echo()
296+
297+
# Summary
298+
installed_count = len(all_packages) - len(missing_packages)
299+
click.echo(f"📊 Summary: {installed_count}/{len(all_packages)} packages installed")
300+
301+
if missing_packages:
302+
click.echo()
303+
click.echo("❌ Missing Packages:")
304+
for pkg in missing_packages:
305+
click.echo(f" - {pkg}")
306+
307+
click.echo()
308+
click.echo("💡 To install missing packages, run in R:")
309+
missing_str = '", "'.join(missing_packages)
310+
click.echo(f' install.packages(c("{missing_str}"))')
311+
312+
click.echo()
313+
click.echo("🚀 Or install all RMCP packages at once:")
314+
all_str = '", "'.join(all_packages)
315+
click.echo(f' install.packages(c("{all_str}"), repos="https://cran.rstudio.com/")')
316+
else:
317+
click.echo()
318+
click.echo("🎉 All required R packages are installed!")
319+
click.echo("✅ RMCP is ready to use!")
320+
321+
242322
def _load_config(config_file: str) -> dict:
243323
"""Load configuration from file."""
244324
import json

rmcp/r_integration.py

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,59 @@ def execute_r_script(script: str, args: Dict[str, Any]) -> Dict[str, Any]:
163163
)
164164

165165
if process.returncode != 0:
166+
# Enhanced error handling for missing packages
166167
error_msg = f"R script failed with return code {process.returncode}"
167-
logger.error(f"{error_msg}\\nStderr: {process.stderr}")
168+
stderr = process.stderr or ""
169+
170+
# Check for common R package errors
171+
if "there is no package called" in stderr:
172+
# Extract package name from error
173+
import re
174+
match = re.search(r"there is no package called '([^']+)'", stderr)
175+
if match:
176+
missing_pkg = match.group(1)
177+
# Map package to feature category
178+
pkg_features = {
179+
"plm": "Panel Data Analysis", "lmtest": "Statistical Testing",
180+
"sandwich": "Robust Standard Errors", "AER": "Applied Econometrics",
181+
"jsonlite": "Data Exchange", "forecast": "Time Series Forecasting",
182+
"vars": "Vector Autoregression", "urca": "Unit Root Testing",
183+
"tseries": "Time Series Analysis", "nortest": "Normality Testing",
184+
"car": "Regression Diagnostics", "rpart": "Decision Trees",
185+
"randomForest": "Random Forest", "ggplot2": "Data Visualization",
186+
"gridExtra": "Plot Layouts", "tidyr": "Data Tidying",
187+
"rlang": "Programming Tools", "dplyr": "Data Manipulation"
188+
}
189+
190+
feature = pkg_features.get(missing_pkg, "Statistical Analysis")
191+
error_msg = f"""❌ Missing R Package: '{missing_pkg}'
192+
193+
🔍 This package is required for: {feature}
194+
195+
📦 Install with:
196+
install.packages("{missing_pkg}")
197+
198+
🚀 Or install all RMCP packages:
199+
install.packages(c("jsonlite", "plm", "lmtest", "sandwich", "AER", "dplyr", "forecast", "vars", "urca", "tseries", "nortest", "car", "rpart", "randomForest", "ggplot2", "gridExtra", "tidyr", "rlang"))
200+
201+
💡 Check package status: rmcp check-r-packages"""
202+
203+
elif "could not find function" in stderr:
204+
error_msg = f"""❌ R Function Error
205+
206+
The R script failed because a required function is missing. This usually means:
207+
1. A required package is not loaded
208+
2. A package is installed but not the right version
209+
210+
💡 Try: rmcp check-r-packages
211+
212+
Original error: {stderr.strip()}"""
213+
214+
logger.error(f"{error_msg}\\nOriginal stderr: {stderr}")
168215
raise RExecutionError(
169216
error_msg,
170217
stdout=process.stdout,
171-
stderr=process.stderr,
218+
stderr=stderr,
172219
returncode=process.returncode
173220
)
174221

0 commit comments

Comments
 (0)