Spaces:
Running
Running
| # 20251009 Added plot tool | |
| # 20251023 Added help tools | |
| # Load ellmer for tool() and type_*() | |
| library(ellmer) | |
| # Read prompts | |
| source("prompts.R") | |
| # Get help for a package | |
| help_package <- function(package) { | |
| help_page <- help(package = (package), help_type = "text") | |
| paste(unlist(help_page$info), collapse = "\n") | |
| } | |
| # Get help for a topic | |
| # Adapted from https://github.com/posit-dev/btw:::help_to_rd | |
| help_topic <- function(topic) { | |
| help_page <- help(topic = (topic), help_type = "text") | |
| if(length(help_page) == 0) { | |
| return(paste0("No help found for '", topic, "'. Please check the name and try again.")) | |
| } | |
| # Handle multiple help files for a topic | |
| # e.g. help_topic(plot) returns the help for both base::plot and graphics::plot.default | |
| help_paths <- as.character(help_page) | |
| help_result <- sapply(help_paths, function(help_path) { | |
| rd_name <- basename(help_path) | |
| rd_package <- basename(dirname(dirname(help_path))) | |
| db <- tools::Rd_db(rd_package)[[paste0(rd_name, ".Rd")]] | |
| paste(as.character(db), collapse = "") | |
| }) | |
| # Insert headings to help the LLM distinguish multiple help files | |
| # Heading before each help file (e.g. Help file 1, Help file 2) | |
| help_result <- paste0("## Help file ", seq_along(help_result), ":\n", help_result) | |
| # Heading at start of message (e.g. 2 help files were retrieved) | |
| if(length(help_paths) == 1) help_info <- paste0("# ", length(help_paths), " help file was retrieved: ", paste(help_paths, collapse = ", "), ":\n") | |
| if(length(help_paths) > 1) help_info <- paste0("# ", length(help_paths), " help files were retrieved: ", paste(help_paths, collapse = ", "), ":\n") | |
| help_result <- c(help_info, help_result) | |
| help_result | |
| } | |
| # Run R code and return the result | |
| # https://github.com/posit-dev/mcptools/issues/71 | |
| run_visible <- function(code) { | |
| eval(parse(text = code), globalenv()) | |
| } | |
| # Run R code without returning the result | |
| # https://github.com/posit-dev/mcptools/issues/71 | |
| run_hidden <- function(code) { | |
| eval(parse(text = code), globalenv()) | |
| return("The code executed successfully") | |
| } | |
| # Run R code to make a plot and return the image data | |
| make_plot <- function(code) { | |
| # Cursor, Bing and Google AI all suggest this but it causes an error: | |
| # Error in png(filename = raw_conn) : | |
| # 'filename' must be a non-empty character string | |
| ## Write plot to an in-memory PNG | |
| #raw_conn <- rawConnection(raw(), open = "wb") | |
| #png(filename = raw_conn) | |
| # Use a temporary file to save the plot | |
| filename <- tempfile(fileext = ".dat") | |
| on.exit(unlink(filename)) | |
| # Run the plotting code (this should include e.g. png() and dev.off()) | |
| # The code uses a local variable (filename), so don't use envir = globalenv() here | |
| eval(parse(text = code)) | |
| # Return a PNG image as raw bytes so ADK can save it as an artifact | |
| readr::read_file_raw(filename) | |
| } | |
| # This is the same code as make_plot() but has a different tool description | |
| make_ggplot <- function(code) { | |
| filename <- tempfile(fileext = ".dat") | |
| on.exit(unlink(filename)) | |
| eval(parse(text = code)) | |
| readr::read_file_raw(filename) | |
| } | |
| mcptools::mcp_server(tools = list( | |
| tool( | |
| help_package, | |
| help_package_prompt, | |
| arguments = list( | |
| package = type_string("Package to get help for.") | |
| ) | |
| ), | |
| tool( | |
| help_topic, | |
| help_topic_prompt, | |
| arguments = list( | |
| topic = type_string("Topic or function to get help for.") | |
| ) | |
| ), | |
| tool( | |
| run_visible, | |
| run_visible_prompt, | |
| arguments = list( | |
| code = type_string("R code to run.") | |
| ) | |
| ), | |
| tool( | |
| run_hidden, | |
| run_hidden_prompt, | |
| arguments = list( | |
| code = type_string("R code to run.") | |
| ) | |
| ), | |
| tool( | |
| make_plot, | |
| make_plot_prompt, | |
| arguments = list( | |
| code = type_string("R code to make the plot.") | |
| ) | |
| ), | |
| tool( | |
| make_ggplot, | |
| make_ggplot_prompt, | |
| arguments = list( | |
| code = type_string("R code to make the plot.") | |
| ) | |
| ) | |
| )) | |