水管2mcp
 
通过单个函数调用将模型上下文协议(MCP)支持添加到Plumber API中。
什么是MCP?
模型上下文协议(MCP)是一种标准协议,使AI助手(如Claude、ChatGPT等)能够与外部工具和服务进行交互。通过将MCP支持添加到您的Plumber API,您可以将R功能提供为:
- 工具:人工智能助手可以直接调用您的API端点
- 资源:AI助手可以读取文档、数据和分析结果
- 提示词:AI助手可以使用预定义的模板来指导交互
安装
# Install from GitHub
remotes::install_github("armish/plumber2mcp")依赖项
此软件包要求:
- R(>=4.0.0)
- 水管工(>=1.0.0)
- Jsonlite
- 高温工程试验堆
快速开始
HTTP传输(默认)
library(plumber)
library(plumber2mcp)
# Create and run a Plumber API with MCP support via HTTP
pr("plumber.R") %>%
pr_mcp(transport = "http") %>%
pr_run(port = 8000)您的API现在具有:
- 常规HTTP端点位于
http://localhost:8000/ - MCP服务器位于
http://localhost:8000/mcp
标准传输(本地MCP)
library(plumber)
library(plumber2mcp)
# Create and run a Plumber API with native stdio transport
pr("plumber.R") %>%
pr_mcp(transport = "stdio")与mcp-cli或其他mcp客户端一起使用:
- 创建一个
server_config.json文件:
{
"mcpServers": {
"plumber2mcp": {
"command": "Rscript",
"args": ["-e", "plumber::pr('api.R') %>% plumber2mcp::pr_mcp(transport='stdio')"],
"cwd": "."
}
}
}- 测试连接:
mcp-cli servers # Should show your server as "Ready"
mcp-cli tools # List available tools
mcp-cli cmd --tool GET__echo --tool-args '{"msg": "Hello!"}' # Call a tool运作原理
这 pr_mcp() 自动功能:
- 发现您的端点:扫描Plumber API中的所有端点
- 创建MCP工具:将每个端点转换为具有适当架构的MCP工具
- 添加MCP端点:添加必要的MCP协议端点
- 处理JSON-RPC:通过JSON-RPC管理所有MCP通信
- 支持资源:允许AI助手从R环境中读取文档和数据
- 支持提示:公开可重用的提示模板,指导人工智能交互
- 生成丰富的模式:使用您的roxygen注释中的文档创建详细的输入/输出模式
增强的文档和模式生成
plumber2mcp通过分析您的roxygen注释和函数签名,自动为您的API端点生成丰富的JSON模式和详细的文档。此功能受FastAPI MCP的启发,使您的R API更容易被AI助手使用。
丰富的工具描述
当您使用roxygen注释记录端点时,管道工2mcp会创建全面的工具描述:
#* Calculate statistical operations on numeric data
#*
#* This endpoint performs various statistical calculations on a vector of numbers.
#* It supports multiple operations and handles missing values.
#*
#* @param numbers Numeric vector of values to calculate statistics for
#* @param operation Statistical operation to perform: "mean", "median", "sum", "sd" (default: "mean")
#* @param na_rm:bool Logical value indicating whether to remove NA values (default: TRUE)
#* @param digits:int Number of decimal places to round the result (default: 2)
#* @return List containing the calculated result and metadata
#* @post /calculate
function(numbers, operation = "mean", na_rm = TRUE, digits = 2) {
# Convert input to numeric
if (is.character(numbers)) {
numbers %
pr_mcp(transport = "stdio") %>%
pr_mcp_prompt(
name = "r-help",
description = "Get help with R programming",
func = function() {
paste(
"I need help with R programming.",
"Please provide guidance on best practices and common patterns.",
sep = "\n"
)
}
)
# Prompt with arguments
pr %>%
pr_mcp(transport = "stdio") %>%
pr_mcp_prompt(
name = "analyze-dataset",
description = "Generate a comprehensive analysis plan for an R dataset",
arguments = list(
list(
name = "dataset",
description = "Name of the R dataset to analyze",
required = TRUE
),
list(
name = "focus",
description = "Specific aspect to focus on",
required = FALSE
)
),
func = function(dataset, focus = "general") {
sprintf(
paste(
"Please analyze the %s dataset in R.",
"Focus: %s",
"",
"Provide:",
"1. Summary statistics",
"2. Data quality assessment",
"3. Key insights",
sep = "\n"
),
dataset, focus
)
}
)
# Multi-turn conversation prompt
pr %>%
pr_mcp(transport = "stdio") %>%
pr_mcp_prompt(
name = "code-review",
description = "Review R code for quality and best practices",
arguments = list(
list(name = "code", description = "The R code to review", required = TRUE)
),
func = function(code) {
list(
list(
role = "user",
content = list(
type = "text",
text = paste("Please review this R code:", code, sep = "\n\n")
)
),
list(
role = "assistant",
content = list(
type = "text",
text = "I'll review your code for correctness, performance, and style."
)
),
list(
role = "user",
content = list(
type = "text",
text = "Please provide specific suggestions for improvement."
)
)
)
}
)提示消息格式
提示函数可以以多种格式返回消息:
- 简单字符串 -自动转换为用户消息:
func = function() "Hello World"- 结构化消息 -完全控制角色和内容:
func = function() {
list(
role = "user",
content = list(type = "text", text = "Your message")
)
}- 多条消息 -对于多回合对话:
func = function() {
list(
list(role = "user", content = list(type = "text", text = "First message")),
list(role = "assistant", content = list(type = "text", text = "Second message"))
)
}提示用例
工作流程指导
pr_mcp_prompt(
pr,
name = "data-pipeline",
description = "Guide for building data processing pipelines",
arguments = list(
list(name = "data_type", description = "Type of data to process", required = TRUE)
),
func = function(data_type) {
sprintf("Create a data processing pipeline for %s data...", data_type)
}
)代码生成模板
pr_mcp_prompt(
pr,
name = "create-endpoint",
description = "Template for creating new Plumber endpoints",
func = function() {
paste(
"Generate a Plumber endpoint with:",
"1. Proper roxygen documentation",
"2. Input validation",
"3. Error handling",
"4. Example usage",
sep = "\n"
)
}
)领域特定协助
pr_mcp_prompt(
pr,
name = "statistical-test",
description = "Choose and implement appropriate statistical tests",
arguments = list(
list(name = "research_question", description = "Research question", required = TRUE)
),
func = function(research_question) {
sprintf(
paste(
"Research Question: %s",
"",
"Help me:",
"1. Choose the appropriate statistical test",
"2. Check assumptions",
"3. Implement in R",
"4. Interpret results",
sep = "\n"
),
research_question
)
}
)示例:使用提示完成设置
library(plumber)
library(plumber2mcp)
pr("api.R") %>%
pr_mcp(transport = "stdio") %>%
# Add analysis prompt
pr_mcp_prompt(
name = "analyze",
description = "Analyze data from the API",
func = function() {
"Guide me through analyzing the data available from this API."
}
) %>%
# Add troubleshooting prompt
pr_mcp_prompt(
name = "troubleshoot",
description = "Help troubleshoot API issues",
arguments = list(
list(name = "issue", description = "Description of the issue", required = TRUE)
),
func = function(issue) {
sprintf("I'm experiencing this issue with the API: %s\n\nHow can I resolve it?", issue)
}
)资源支持
资源允许AI助手从R环境中读取内容,如文档、数据描述或分析结果。
添加自定义资源
# Create a Plumber API with resources
pr(...) %>%
pr_mcp(transport = "stdio") %>%
# Add a resource that provides dataset information
pr_mcp_resource(
uri = "/data/iris-summary",
func = function() {
paste(
"Dataset: iris",
paste("Dimensions:", paste(dim(iris), collapse = " x ")),
"",
capture.output(summary(iris)),
sep = "\n"
)
},
name = "Iris Dataset Summary",
description = "Statistical summary and structure of the iris dataset"
) %>%
# Add a resource that shows current memory usage
pr_mcp_resource(
uri = "/system/memory",
func = function() {
mem %
# Add a resource with model diagnostics
pr_mcp_resource(
uri = "/models/latest-lm",
func = function() {
# Example: fit a model and return diagnostics
model %
pr_mcp(transport = "stdio") %>%
pr_mcp_help_resources() # Adds help for common R functions这会自动为以下内容添加资源:
- R帮助主题(
/help/mean,/help/lm等等) - R会话信息(
/r/session-info) - 已安装的软件包(
/r/packages)
带参数的动态资源
虽然当前的实现不支持URI模板,但您可以创建根据运行时条件进行调整的资源:
# Create resources based on available data files
data_files %
pr_mcp_resource(
uri = paste0("/data/", tools::file_path_sans_ext(file)),
func = local({
current_file % pr_mcp(transport = "http", path = "/my-mcp-server")筛选端点
# Include only specific endpoints
my_pr %>% pr_mcp(transport = "http", include_endpoints = c("GET__echo", "POST__add"))
# Exclude specific endpoints
my_pr %>% pr_mcp(transport = "stdio", exclude_endpoints = c("POST__internal"))自定义服务器信息
my_pr %>% pr_mcp(
transport = "http",
server_name = "my-api-mcp",
server_version = "1.0.0"
)完整示例
以下是创建启用MCP的API的分步示例:
- 创建水管工API文件(
my_api.R):
#* @apiTitle My MCP-Enabled API
#* @apiDescription API with MCP support for AI assistants
#* Get current time
#* @get /time
function() {
list(time = Sys.time())
}
#* Calculate factorial
#* @param n Integer to calculate factorial
#* @post /factorial
function(n) {
n %
pr_mcp(transport = "http") %>%
pr_run(port = 8000)- 您的API现在可以访问:
- HTTP API: http://localhost:8000/ - MCP端点: http://localhost:8000/mcp - API文件: http://localhost:8000/__docs__/
测试
运行示例服务器:
source(system.file("examples/run_mcp_server.R", package = "plumber2mcp"))使用MCP客户端进行测试:
source(system.file("examples/test_mcp_client.R", package = "plumber2mcp"))使用AI助手
MCP服务器运行后,您可以配置AI助手来使用它:
克劳德桌面
添加到您的Claude配置文件中:
{
"mcpServers": {
"my-r-api": {
"url": "http://localhost:8000/mcp"
}
}
}其他人工智能助理
查看AI助手的文档,了解MCP配置说明。
MCP协议详细信息
此包实现了 模型上下文协议 规范。MCP端点处理:
- 工具发现:将所有可用的Plumber端点作为MCP工具列出
- 工具执行:将MCP工具调用转换为Plumber端点请求
- 错误处理:正确格式化MCP响应格式中的错误
MCP检验员测试
MCP检查员 是用于测试和调试MCP服务器的工具。
在HTTP传输中使用MCP检查器
- 使用HTTP传输启动水管工API:
library(plumber)
library(plumber2mcp)
pr("api.R") %>%
pr_mcp(transport = "http") %>%
pr_run(port = 8000)- 在新终端中,导航到示例目录:
cd /path/to/plumber2mcp/inst/examples
mcp-inspector --config http_wrapper_config.json --server plumber2mcp这 stdio-wrapper.py 该脚本将MCP Inspector的stdio接口连接到您的HTTP服务器。
使用带标准传输的MCP检查器
直接使用stdio配置:
cd /path/to/plumber2mcp/inst/examples
mcp-inspector --config stdio_config.json --server plumber2mcp故障排除
常见问题
- 端口已在使用中:更改中的端口号
pr_run(port = 8001) - 未找到MCP端点:确保你打过电话
pr_mcp()之前pr_run() - 工具未显示:检查Plumber端点是否具有正确的注释
- MCP检查器连接错误:
- 对于HTTP:在启动MCP检查器之前,确保服务器在端口8000上运行 - 检查一下 cwd 配置文件中的路径指向正确的目录
调试模式
启用详细日志记录:
# For stdio transport
my_pr %>% pr_mcp(transport = "stdio", debug = TRUE)
# For HTTP transport (debug not available)
my_pr %>% pr_mcp(transport = "http") %>% pr_run(port = 8000)贡献
欢迎投稿!请在GitHub上提交问题和拉取请求。
许可证
麻省理工学院
