Lets coding agents run a shiny module of an R package,
set its inputs, read its arguments, return values and outputs,
and screenshot it,
through the Model Context Protocol.
The module runs in module2app_bare(),
the testbed without displays for humans.
Value
crow_tools(): A named list ofellmer::tool()s.crow_mcp_server(): Does not return; serves the tools until the MCP client disconnects.
Details
The tools offer two tiers of cost:
module_test_serverrunsshiny::testServer()onmodule2app_bare_server()in a new R process, without a browser. It takes a few seconds and keeps no state.module_app_startrunsmodule2app_bare()in a new R process and drives it withshinytest2::AppDriverin Chrome. It takes about ten seconds to start, and runs untilmodule_app_stop.module_app_set,module_app_getandmodule_app_screenshotuse the running app.
All tools report the server arguments and return values
as unevaluated and evaluated trees (see mixed_react_tree()),
the raw events of shiny::reactlog() on request,
and the logs of their R and shiny processes,
errors first.
Every tool starts its R processes in path,
the package root with the DESCRIPTION,
and loads the package from there with pkgload::load_all(),
so it runs the working tree, not an installed version.
Running apps load the package when they start;
restart them after changing the package.
Each app runs in its own processes,
which end when the app or the MCP server stops.
Security
The tools evaluate the R code that the agent passes,
such as server_args,
with the rights of the user running the MCP server.
Only a sandbox around the agent and the MCP server
isolates your system from that code.
Changes to running apps (module_app_set) accept only JSON,
because the apps listen on local websockets
that any web page in the same browser could reach.
See also
Other agentic coding:
module2app_bare_ui()
Examples
if (FALSE) { # \dontrun{
# combine with btw's tools for documentation and package development
mcptools::mcp_server(
c(btw::btw_tools(c("docs", "pkg")), crow::crow_tools()),
session_tools = FALSE
)
} # }