The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
The mcptools package enables apps like Claude Desktop, Claude Code, and VS Code GitHub Copilot to run R code using the Model Context Protocol (MCP). This vignette highlights the basics of using mcptools to launch R-based MCP servers before delving a bit further into advanced usage.
In the context of R as an MCP server, there are three main concepts to understand:
Clients are the apps you’d like to connect an R session to, like Claude Desktop of Claude Code. mcptools supports any client that supports MCP.
Clients can run R functions as tools using an MCP
server. Each client that supports MCP will provide some
entry point to configure a command and any additional arguments with the
client. mcptools’s command and arguments are Rscript
and
-e "mcptools::mcp_server()"
. Different clients register
this command in different ways. For example, to use mcptools with the
client Claude Code, you might write
claude mcp add -s "user" r-mcptools -- Rscript -e "mcptools::mcp_server()"
.
Sessions are the R sessions that the client
ultimately talks to. So, if you have an RStudio or Positron window open,
those applications automatically start up an R session that the client
could potentially talk to. To “opt in” your R sessions to be discovered
by clients, run the R code mcptools::mcp_session()
. You
might want to run this code every time you start up R; to do so, add
mcptools::mcp_session()
to your .Rprofile
,
perhaps by first calling usethis::edit_r_profile()
.
Configuring sessions is not required; if you choose not
to do so, tools will be executed in the server itself.
(In case this caught your eye: yes, the server is itself an R session. In mcptools’s documentation, we’ll always refer to the server R session just as the server; the fact that it’s implemented in R is only a technical detail.)
In the case you have some client that you want to connect to R,
all you need to do is configure the command
Rscript -e "mcptools::mcp_server()"
according to your
client’s instructions. Optionally, if you’d like the server to be able
to access variables in interactive R sessions, add
mcptools::mcp_session()
to your .Rprofile
,
perhaps by first calling usethis::edit_r_profile()
.
Then, you’re good to go!
While a single client (and potentially a single R session) probably covers many users’ use cases, mcptools supports multiple clients and multiple R sessions. For example, for the former, you may be both chatting in Claude Desktop and running Claude Code in a terminal somewhere. Or, in the multiple R sessions situation, you may have two or more Positron instances running at once, with different data science projects in each.
As for multiple clients, this will “just work”; there’s nothing to keep in mind here.
As for multiple R sessions, mcptools will choose a
default R session for your model to talk to without the client knowing
it even had multiple options. So, you might have a project “goats” open
in one Positron window and another project, “sheep”, open in another
Positron window. mcptools provides models with two tools to facilitate
toggling between sessions. The first, list_r_sessions()
,
allows the client to “discover” R sessions available to it by their
working directory and (inferred) IDE. Then, the tool
select_r_session()
allows the client to (persistently)
choose an R session. So, you could write “In my goats R session, \[some question\].” In that case, the model
might call list_r_sessions()
to find the full identifier
for that goats session, then select_r_session()
, then
whatever other tools it will use to respond to your question. Notably,
if you ask a follow-up question (and you haven’t closed the Positron
window with goats pulled up in the meantime) in the same client chat,
the client doesn’t need to use list_r_sessions()
and
select_r_session()
again, and can just call whatever tools
it needs to answer your follow-up.
As for both multiple clients and multiple R
sessions, this will generally “just work.” That said, do note
that clients can only be connected to one R session at a time. For most
clients, like Claude Code, this isn’t much of an issue. For chat apps
like Claude Desktop, though, you may run into hiccups when you have
multiple chats actively going at the same time. For example, imagine I
ask Claude via Claude Desktop about some problem in my R session “goats”
and then, a moment later, spin up a different chat and ask about my
“sheep” project. In the second chat, Claude will likely use
select_r_session()
to choose the “sheep” project. If I then
go back to the chat about “goats” and ask a follow-up, the R session
that any tool calls dispatch to will actually also be the “sheep”
project. If the tool call, say, reads documentation, this isn’t an
issue. If the tool call describe some variable in the global
environment, though, the value of that variable may not exist in—or be
different in—the “sheep” project.
By default, mcptools supplies clients with only the necessary infrastructural tools to implement interaction with active sessions. You may be interested in using mcptools via btw’s wrappers, which provide a set of atomic tools for data science. These tools allow clients to:
Peruse package documentation
Describe R session information and variables from the global environment
Run queries against data sources
Users might be interested in extending these tools or supplying completely different ones. For example, you might register:
run_r_code()
that allows a client
to run whatever R code it wants.You can configure any set of tools that could be passed to the
$set_tools()
method of an ellmer Chat object as the tools
that mcptools will supply to clients. To do so, supply a list of outputs
from ellmer::tool()
to the tools
argument of
mcp_server()
. Relatedly, you’ll need to make sure that your
code that specifies the new tools can run in a fresh R session; be sure
to either namespace functions from libraries (like
ellmer::tool()
instead of tool()
) or load the
libraries entirely.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.