Introduction
The Model Context Protocol (MCP) allows Large Language Models like
Claude to interact with external tools and data sources. However, R’s
stdin handling in subprocess contexts requires special handling. The
mcpr
package solves this by providing Node.js wrapper
templates that properly manage communication between MCP clients and R
servers.
Quick Start
Generating a Simple Server
library(mcpr)
# Generate a basic MCP server
generate_mcp_server(
name = "hello-world",
title = "Hello World Server",
description = "A simple MCP server that greets users"
)
This creates a complete server package in
./mcp-hello-world/
with: - wrapper.js
-
Node.js wrapper that handles stdin/stdout - server.R
- R
server implementation - package.json
- NPM package
configuration - test.js
- Test script to validate the
server - README.md
- Documentation
Creating Servers with Tools
Basic Example
# Define tools
tools <- list(
greet = list(
description = "Greet a person by name",
parameters = list(
name = list(type = "string", description = "Name to greet")
)
),
calculate = list(
description = "Evaluate an R expression",
parameters = list(
expression = list(type = "string", description = "R expression to evaluate")
)
)
)
# Generate server with tools
generate_mcp_server(
name = "my-tools",
title = "My R Tools",
description = "Useful R tools for data analysis",
tools = tools
)
Using the Programmatic API
# Create server programmatically
server <- mcp(name = "Data Analyzer", version = "1.0.0")
# Add tools
server$mcp_tool(
name = "summarize",
fn = function(data) {
summary(data)
},
description = "Summarize a dataset"
)
server$mcp_tool(
name = "correlation",
fn = function(x, y) {
cor(x, y)
},
description = "Calculate correlation"
)
# Generate standalone package
server$generate(path = "./servers", template = "full")
Working with Resources
Resources provide read-only access to data:
resources <- list(
list(
uri = "data://iris",
name = "Iris Dataset",
description = "Classic iris dataset"
),
list(
uri = "info://system",
name = "System Information",
description = "R system information"
)
)
generate_mcp_server(
name = "data-provider",
title = "Data Provider",
description = "Provides access to datasets",
resources = resources
)
Using Configuration Files
YAML Configuration
Create server-config.yaml
:
name: analysis-server
title: Statistical Analysis Server
description: Comprehensive statistical analysis tools
version: 1.0.0
author: Your Name
tools:
t_test:
description: Perform t-test
parameters:
x:
type: array
description: First sample
y:
type: array
description: Second sample
regression:
description: Linear regression
parameters:
formula:
type: string
description: Model formula
data:
type: object
description: Data frame
resources:
- uri: "data://example"
name: "Example Data"
description: "Sample datasets"
Generate from configuration:
generate_from_config("server-config.yaml")
JSON Configuration
# Create example configuration
create_example_config("server-config.json", format = "json")
# Generate from JSON
generate_from_config("server-config.json")
Templates
Full Template
The default “full” template includes: - Complete MCP protocol implementation - Support for tools, resources, and prompts - Comprehensive error handling - Detailed comments and documentation
Minimal Template
For simple use cases:
generate_mcp_server(
name = "simple",
title = "Simple Server",
description = "Minimal MCP server",
template = "minimal"
)
Advanced Usage
HTTP Transport (New!)
As of version 0.1.0, mcpr supports HTTP transport as an alternative to stdio. HTTP transport offers several advantages:
- Multiple concurrent clients: Unlike stdio which is limited to one client, HTTP servers can handle multiple connections
- Easier debugging: Use standard HTTP tools like curl or Postman
- Better deployment options: Deploy to cloud platforms, containers, or behind load balancers
- No subprocess complexity: Avoids R’s stdin handling limitations
Creating an HTTP Server
# Using the convenience function
server <- mcp_http(
name = "My HTTP Server",
version = "1.0.0",
host = "127.0.0.1",
port = 8080
)
# Add tools, resources, and prompts as usual
server$mcp_tool(
name = "analyze",
fn = function(data) { summary(as.numeric(strsplit(data, ",")[[1]])) },
description = "Analyze comma-separated numbers"
)
# Start the server
server$mcp_run() # Automatically uses HTTP transport
Quick Start with HTTP
# Start a hello world HTTP server
mcp_hello_world_http(port = 8080)
# Test it with curl
# curl -X POST http://localhost:8080/mcp \
# -H "Content-Type: application/json" \
# -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
HTTP Server Features
-
Built-in endpoints:
-
POST /mcp
- Main MCP protocol endpoint -
GET /health
- Health check endpoint -
GET /
- Server information
-
-
Logging support:
server <- mcp_http( name = "Logged Server", log_file = "server.log", log_level = "debug" # debug, info, warn, error )
-
Swagger documentation (when enabled):
server$mcp_run(docs = TRUE) # Visit http://localhost:8080/__docs__
Using with Claude Desktop
For Claude Desktop configuration with HTTP servers:
{
"mcpServers": {
"my-http-server": {
"command": "Rscript",
"args": ["-e", "library(mcpr); server <- mcp_http('My Server'); server$mcp_tool('hello', function(name='World') paste('Hello', name)); server$mcp_run()"]
}
}
}
Or create a script file:
Deployment Options
HTTP servers can be deployed to:
- Local development: Run on localhost for testing
- Docker containers: Package your server as a container
- Cloud platforms: Deploy to Heroku, Google Cloud Run, etc.
- Posit Connect: Deploy R-based HTTP APIs
- Corporate networks: Run behind firewalls with proper authentication
Troubleshooting
Best Practices
- Always use the Node.js wrapper - Direct R execution won’t work with Claude Desktop
-
Keep stderr clean - Use
suppressMessages()
andsuppressWarnings()
in your R code - Test thoroughly - Use the included test script before deployment
- Document your tools - Provide clear descriptions for better LLM understanding
Example: Complete Data Analysis Server
# Create a comprehensive data analysis server
tools <- list(
read_csv = list(
description = "Read CSV file",
parameters = list(
path = list(type = "string", description = "File path")
)
),
summarize = list(
description = "Generate summary statistics",
parameters = list(
data = list(type = "object", description = "Data frame")
)
),
plot_histogram = list(
description = "Create histogram",
parameters = list(
data = list(type = "array", description = "Numeric data"),
bins = list(type = "number", description = "Number of bins")
)
),
linear_model = list(
description = "Fit linear model",
parameters = list(
formula = list(type = "string", description = "Model formula"),
data = list(type = "object", description = "Data frame")
)
)
)
resources <- list(
list(
uri = "data://sample",
name = "Sample Datasets",
description = "Built-in R datasets"
)
)
prompts <- list(
analyze = list(
description = "Analyze a dataset comprehensively"
)
)
generate_mcp_server(
name = "data-analysis",
title = "R Data Analysis Server",
description = "Complete data analysis toolkit",
tools = tools,
resources = resources,
prompts = prompts,
author = "Data Science Team"
)