Build MCP servers in R and call external MCP tools
R package implementing MCP both ways - run R code as an MCP server for Claude Desktop and Copilot, or register third-party MCP servers as an R client.
Why it matters
Enable R developers to create Model Context Protocol servers that expose R functionality to AI systems, and to consume third-party MCP servers as native R functions within their workflows.
Outcomes
What it gets done
Create R-based MCP servers that expose R functions to AI assistants
Connect to third-party MCP servers from R environments
Retrieve functionality from external MCP servers as callable R functions
Integrate R data science workflows with the MCP ecosystem
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/mcp-r-mcptools | bash Overview
R mcptools
An R package implementing the Model Context Protocol on both sides: mcp_server() exposes R code execution and session inspection to MCP clients like Claude Desktop and VS Code Copilot, while mcp_tools() lets an R-based chat, via ellmer, call third-party MCP servers as a client. Use the server side when an AI assistant needs to run R code or inspect a live R session's variables. Use the client side to give an ellmer-based R chat access to external MCP servers like GitHub or Google Drive.
What it does
mcptools implements the Model Context Protocol in R, on both sides of the connection. As an MCP server, it lets MCP-enabled tools like Claude Desktop, Claude Code, and VS Code GitHub Copilot run R code directly in a developer's actual running R sessions to answer questions - not a sandboxed re-execution, but the real session with its real loaded data and objects. As an MCP client, it lets R code register third-party MCP servers and expose them as tools to an ellmer chat, so an R-based conversational app can pull in context from services like GitHub, Confluence, or Google Drive.
When to use - and when NOT to
Use the server side when an AI assistant should be able to answer questions grounded in a specific R session's actual state - describing a data frame's structure, checking what year range a dataset covers, or reading the documentation of installed packages - rather than the assistant reasoning about code it can't run. The companion btw package adds a ready-made set of tools, package documentation lookup, global environment inspection, session and platform metadata, instead of requiring every tool to be hand-configured. Use the client side when building an R chat application, such as with shinychat or querychat, that needs to pull in external context through existing MCP servers rather than reimplementing each integration in R. The package is explicitly labeled experimental via its lifecycle badge, so API changes should be expected before a stable release.
Inputs and outputs
Server side: mcp_server() starts the MCP server process, typically launched by the MCP client itself via Rscript -e mcptools::mcp_server(); mcp_session(), called inside a specific interactive R session, registers that session so its variables and state become queryable, and can be added to .Rprofile to auto-register every session on startup. Client side: mcp_tools() reads a Claude-Desktop-format configuration file, by default at ~/.config/mcptools/config.json, and returns a list of ellmer tools that can be passed to $set_tools() on an ellmer chat object, after which the chat can call those external MCP servers' tools directly.
Integrations
Compatible MCP clients on the server side include Claude Desktop, Claude Code, VS Code GitHub Copilot Chat, and Positron Assistant. The package can also be deployed as an HTTP MCP server to Posit Connect, by adding a _server.yml with engine: mcptools and a tools.R file, then deploying with rsconnect::deployAPI() and marking the content category as mcp. On the client side, it reuses the Claude Desktop config file format to register any third-party MCP server, demonstrated with GitHub's official MCP server, and integrates with ellmer-based R chat apps including shinychat and querychat.
Who it's for
R developers and data scientists who want an AI assistant to work directly against their live R session's data, or who are building R-based chat applications that need access to external services through existing MCP servers instead of custom integrations for each.
Source README
mcptools 
mcptools implements the Model Context
Protocol in R. There are two sides to
mcptools:
R as an MCP server:
When configured with mcptools, MCP-enabled tools like Claude Desktop,
Claude Code, and VS Code GitHub Copilot can run R code in the sessions
you have running to answer your questions. While the package supports
configuring arbitrary R functions, you may be interested in the
btw package’s integrated support for
mcptools, which provides a default set of tools to to peruse the
documentation of packages you have installed, check out the objects in
your global environment, and retrieve metadata about your session and
platform.
R as an MCP client:
Register third-party MCP servers with
ellmer chats to integrate additional
context into e.g. shinychat
and querychat apps.
Installation
Install mcptools from CRAN with:
install.packages("mcptools")
You can install the development version of mcptools like so:
pak::pak("posit-dev/mcptools")
R as an MCP server
mcptools can be hooked up to any application that supports MCP. For
example, to use with Claude Desktop, you might paste the following in
your Claude Desktop configuration (on macOS, at~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"r-mcptools": {
"command": "Rscript",
"args": ["-e", "mcptools::mcp_server()"]
}
}
}
Or, to use with Claude Code, you might type in a terminal:
claude mcp add -s "user" r-mcptools -- Rscript -e "mcptools::mcp_server()"
Then, if you’d like models to access variables in specific R sessions,
call mcptools::mcp_session() in those sessions. (You might include a
call to this function in your .Rprofile, perhaps usingusethis::edit_r_profile(), to automatically register every session you
start up.)
To deploy an HTTP MCP server to Posit Connect, add a _server.yml file
with engine: mcptools and a tools file:
engine: mcptools
tools: tools.R
Deploy the directory as an R API and mark it as MCP content:
rsconnect::deployAPI(".", contentCategory = "mcp")
If the content URL is https://connect.example.com/content/abc123/, usehttps://connect.example.com/content/abc123/mcp as the MCP endpoint.
If you cannot set contentCategory = "mcp" during deployment, set the
MCP category in Connect after deploying and set minimum processes to at
least 1.
R as an MCP client
mcptools uses the Claude Desktop configuration file format to register
third-party MCP servers, as most MCP servers provide setup instructions
for Claude Desktop in their documentation. For example, here’s what the
official GitHub MCP
server configuration would
look like:
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>"
}
}
}
}
Once the configuration file has been created (by default, mcptools will
look to file.path("~", ".config", "mcptools", "config.json")),mcp_tools() will return a list of ellmer tools which you can pass
directly to the $set_tools() method from ellmer:
ch <- ellmer::chat_anthropic()
ch$set_tools(mcp_tools())
ch$chat("What issues are open on posit-dev/mcptools?")
Example
In Claude Desktop, I’ll write the following:
“From what year is the earliest recorded sample in the
foresteddata
in my Positron session?”
Without mcptools, Claude couldn’t get far here; by default, it can’t run
R code and doesn’t have any way to “speak to” my interactive R sessions.
Using the package, the model asks to describe the data frame using a
structure that will show summary statistics from the data. mcptools will
appropriately route the request to the open Positron session, forwarding
the results back to the model for it to situate in a response.
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.