| Title: | Model Context Protocol for R |
|---|---|
| Description: | Create, run, and connect to Model Context Protocol (MCP) servers, and clients in R. The package provides a framework for implementing MCP-compatible servers with tools, resources, and prompts capabilities, as well as client functionality to interact with MCP servers. It includes a JSON-RPC 2.0 implementation for communication between clients and servers. |
| Authors: | John Coene [aut, cre], Opifex [cph, fnd] |
| Maintainer: | John Coene <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 0.0.2.9000 |
| Built: | 2026-05-31 08:32:03 UTC |
| Source: | https://github.com/devOpifex/mcpr |
Add a capability to an MCP object
add_capability(mcp, capability)add_capability(mcp, capability)
mcp |
An MCP server object |
capability |
A tool, resource, or prompt capability object |
The MCP object with the capability added
Create a new mcp IO
new_client_io(command, args = character(), name, version = "1.0.0") new_client_http(endpoint, name, version = "1.0.0")new_client_io(command, args = character(), name, version = "1.0.0") new_client_http(endpoint, name, version = "1.0.0")
command |
The command to run |
args |
Arguments to pass to the command |
name |
The name of the client |
version |
The version of the client |
endpoint |
The endpoint to connect to |
A new mcp client
This function converts tools from the ellmer package to a format compatible with the mcpr package. It takes an ellmer ToolDef object and creates an mcpr tool object with the appropriate input schema and handler function.
ellmer_to_mcpr_tool(ellmer_tool)ellmer_to_mcpr_tool(ellmer_tool)
ellmer_tool |
An ellmer ToolDef object created with |
An mcpr tool object compatible with new_tool()
new_tool(), ellmer::tool(), add_capability()
## Not run: # Create an ellmer tool ellmer_rnorm <- ellmer::tool( rnorm, "Generate random normal numbers", n = ellmer::type_integer("Number of observations"), mean = ellmer::type_number("Mean value", required = FALSE), sd = ellmer::type_number("Standard deviation", required = FALSE) ) # Convert to mcpr format mcpr_tool <- ellmer_to_mcpr_tool(ellmer_rnorm) # Add to an mcpr server server <- new_server("MyServer", "Test server", "1.0.0") add_capability(server, mcpr_tool) ## End(Not run)## Not run: # Create an ellmer tool ellmer_rnorm <- ellmer::tool( rnorm, "Generate random normal numbers", n = ellmer::type_integer("Number of observations"), mean = ellmer::type_number("Mean value", required = FALSE), sd = ellmer::type_number("Standard deviation", required = FALSE) ) # Convert to mcpr format mcpr_tool <- ellmer_to_mcpr_tool(ellmer_rnorm) # Add to an mcpr server server <- new_server("MyServer", "Test server", "1.0.0") add_capability(server, mcpr_tool) ## End(Not run)
Get the name of a client
get_name(x)get_name(x)
x |
A client object |
The name of the client
Initialize the server with protocol information
initialize(mcp)initialize(mcp)
mcp |
A server object |
A list containing protocol version, server info, and capabilities
This roclet automatically generates MCP (Model Context Protocol) servers from R functions annotated with @mcp tags.
mcp_roclet()mcp_roclet()
## Not run: # Use the roclet in roxygenise roxygen2::roxygenise(roclets = c("rd", "mcpr::mcp_roclet")) ## End(Not run)## Not run: # Use the roclet in roxygenise roxygen2::roxygenise(roclets = c("rd", "mcpr::mcp_roclet")) ## End(Not run)
Create a new prompt
new_prompt(name, description, arguments = list(), handler)new_prompt(name, description, arguments = list(), handler)
name |
Name of the prompt |
description |
Description of the prompt |
arguments |
List of arguments for the prompt |
handler |
Function to handle the prompt execution |
A new prompt capability
prompt <- new_prompt( name = "My Prompt", description = "This is a description", arguments = list( input1 = list( type = "string", description = "Input 1" ), input2 = list( type = "number", description = "Input 2" ) ), handler = function(params) { # Process the prompt request return(list(text = "Generated text from prompt")) } )prompt <- new_prompt( name = "My Prompt", description = "This is a description", arguments = list( input1 = list( type = "string", description = "Input 1" ), input2 = list( type = "number", description = "Input 2" ) ), handler = function(params) { # Process the prompt request return(list(text = "Generated text from prompt")) } )
Create a new resource
new_resource(name, description, uri, mime_type = NULL, handler)new_resource(name, description, uri, mime_type = NULL, handler)
name |
Name of the resource |
description |
Description of the resource |
uri |
URI of the resource |
mime_type |
MIME type of the resource (optional) |
handler |
Function to handle the resource request |
A new resource capability
resource <- new_resource( name = "My Resource", description = "This is a description", uri = "https://example.com/resource", mime_type = "text/plain", handler = function(params) { # Process the resource request return(list(content = "Resource content")) } )resource <- new_resource( name = "My Resource", description = "This is a description", uri = "https://example.com/resource", mime_type = "text/plain", handler = function(params) { # Process the resource request return(list(content = "Resource content")) } )
Create a new MCP object
new_server( name, description, version, tools = list(), resources = list(), prompts = list() ) new_mcp(...)new_server( name, description, version, tools = list(), resources = list(), prompts = list() ) new_mcp(...)
name |
Name of the MCP server |
description |
Description of the MCP server |
version |
Version of the MCP server |
tools |
List of tools (optional) |
resources |
List of resources (optional) |
prompts |
List of prompts (optional) |
... |
Forwarded to |
A new MCP object
mcp <- new_server( name = "My MCP", description = "This is a description", version = "1.0.0" )mcp <- new_server( name = "My MCP", description = "This is a description", version = "1.0.0" )
Create a new tool
new_tool(name, description, input_schema, handler)new_tool(name, description, input_schema, handler)
name |
Name of the tool |
description |
Description of the tool |
input_schema |
Input schema for the tool (must be a schema object) |
handler |
Function to handle the tool execution |
A new tool capability
tool <- new_tool( name = "My Tool", description = "This is a description", input_schema = schema( properties = list( input1 = property_string("Input 1", "Description of input 1"), input2 = property_number("Input 2", "Description of input 2") ) ), handler = function(input) { # Process the input here return(input) } )tool <- new_tool( name = "My Tool", description = "This is a description", input_schema = schema( properties = list( input1 = property_string("Input 1", "Description of input 1"), input2 = property_number("Input 2", "Description of input 2") ) ), handler = function(input) { # Process the input here return(input) } )
Get a prompt with the given parameters
prompts_get(mcp, params, id = NULL)prompts_get(mcp, params, id = NULL)
mcp |
A server object |
params |
Parameters for the prompt request |
id |
Optional request ID for response tracking |
A response object with the prompt results or an error
List all available prompts
prompts_list(mcp)prompts_list(mcp)
mcp |
A server object |
A list containing all available prompts
Create a new properties list
properties(...)properties(...)
... |
Property objects |
A list of property objects
properties <- properties( property_string("Name", "The name of the user", required = TRUE), property_number("Age", "The age of the user in years", minimum = 0) )properties <- properties( property_string("Name", "The name of the user", required = TRUE), property_number("Age", "The age of the user in years", minimum = 0) )
Create an array property definition
property_array( title, description, items, required = FALSE, min_items = NULL, max_items = NULL, unique_items = FALSE )property_array( title, description, items, required = FALSE, min_items = NULL, max_items = NULL, unique_items = FALSE )
title |
Short title for the property |
description |
Longer description of the property |
items |
Schema for the items in the array |
required |
Whether the property is required |
min_items |
Optional minimum number of items |
max_items |
Optional maximum number of items |
unique_items |
Logical indicating if items must be unique |
An array property object
tags_prop <- property_array( "Tags", "List of tags for the user", items = property_string("Tag", "A user tag"), unique_items = TRUE )tags_prop <- property_array( "Tags", "List of tags for the user", items = property_string("Tag", "A user tag"), unique_items = TRUE )
Create a boolean property definition
property_boolean(title, description, required = FALSE)property_boolean(title, description, required = FALSE)
title |
Short title for the property |
description |
Longer description of the property |
required |
Whether the property is required |
A boolean property object
active_prop <- property_boolean( "Active status", "Whether the user account is active", required = TRUE )active_prop <- property_boolean( "Active status", "Whether the user account is active", required = TRUE )
Create an enum property with predefined values
property_enum(title, description, values, required = FALSE)property_enum(title, description, values, required = FALSE)
title |
Short title for the property |
description |
Longer description of the property |
values |
Character vector of allowed values |
required |
Whether the property is required |
An enum property object
status_prop <- property_enum( "Status", "User account status", values = c("active", "pending", "suspended"), required = TRUE )status_prop <- property_enum( "Status", "User account status", values = c("active", "pending", "suspended"), required = TRUE )
Create a number property definition
property_number( title, description, required = FALSE, minimum = NULL, maximum = NULL, exclusive_minimum = NULL, exclusive_maximum = NULL, multiple_of = NULL, integer = FALSE )property_number( title, description, required = FALSE, minimum = NULL, maximum = NULL, exclusive_minimum = NULL, exclusive_maximum = NULL, multiple_of = NULL, integer = FALSE )
title |
Short title for the property |
description |
Longer description of the property |
required |
Whether the property is required |
minimum |
Optional minimum value |
maximum |
Optional maximum value |
exclusive_minimum |
Whether minimum is exclusive |
exclusive_maximum |
Whether maximum is exclusive |
multiple_of |
Optional value the number must be a multiple of |
integer |
Whether the number should be an integer |
A number property object
age_prop <- property_number( "User age", "The age of the user in years", required = TRUE, minimum = 0, integer = TRUE )age_prop <- property_number( "User age", "The age of the user in years", required = TRUE, minimum = 0, integer = TRUE )
Create an object property definition
property_object( title, description, properties, required = FALSE, additional_properties = FALSE )property_object( title, description, properties, required = FALSE, additional_properties = FALSE )
title |
Short title for the property |
description |
Longer description of the property |
properties |
List of property definitions for this object |
required |
Whether the property is required |
additional_properties |
Logical indicating if additional properties are allowed |
An object property object
address_prop <- property_object( "Address", "User's address information", properties = list( street = property_string("Street", "Street address", required = TRUE), city = property_string("City", "City name", required = TRUE), country = property_string("Country", "Country name") ) )address_prop <- property_object( "Address", "User's address information", properties = list( street = property_string("Street", "Street address", required = TRUE), city = property_string("City", "City name", required = TRUE), country = property_string("Country", "Country name") ) )
Create a string property definition
property_string( title, description, required = FALSE, enum = NULL, pattern = NULL, min_length = NULL, max_length = NULL, format = NULL )property_string( title, description, required = FALSE, enum = NULL, pattern = NULL, min_length = NULL, max_length = NULL, format = NULL )
title |
Short title for the property |
description |
Longer description of the property |
required |
Whether the property is required |
enum |
Optional character vector of allowed values |
pattern |
Optional regex pattern the string must match |
min_length |
Optional minimum length |
max_length |
Optional maximum length |
format |
Optional format constraint |
A string property object
name_prop <- property_string( "User name", "The name of the user", required = TRUE, min_length = 2, max_length = 50 )name_prop <- property_string( "User name", "The name of the user", required = TRUE, min_length = 2, max_length = 50 )
Read a JSON-RPC response from a client provider
read(x, timeout = 60 * 1000)read(x, timeout = 60 * 1000)
x |
A client provider |
timeout |
Timeout in milliseconds for reading the response |
The response
This function registers tools from an MCPR client with an ellmer chat instance.
register_mcpr_tools(chat, client)register_mcpr_tools(chat, client)
chat |
An ellmer chat object |
client |
An mcpr client object |
The chat object (invisibly)
List all available resources
resources_list(mcp)resources_list(mcp)
mcp |
A server object |
A list containing all available resources
Read a resource with the given parameters
resources_read(mcp, params, id = NULL)resources_read(mcp, params, id = NULL)
mcp |
A server object |
params |
Parameters for the resource read |
id |
Optional request ID for response tracking |
A response object with the resource read results or an error
Create a response object
response_text(text) response_image(image, mime_type = "image/png") response_audio(audio, mime_type = "audio/mpeg") response_video(video, mime_type = "video/mp4") response_file(file, mime_type = "application/octet-stream") response_resource(resource) response_error(text) response_item( ..., type = c("text", "image", "audio", "video", "file", "resource") ) response(..., is_error = FALSE)response_text(text) response_image(image, mime_type = "image/png") response_audio(audio, mime_type = "audio/mpeg") response_video(video, mime_type = "video/mp4") response_file(file, mime_type = "application/octet-stream") response_resource(resource) response_error(text) response_item( ..., type = c("text", "image", "audio", "video", "file", "resource") ) response(..., is_error = FALSE)
text |
Text content for the response |
image |
Image content |
mime_type |
Mime type of the content |
audio |
Audio content |
video |
Video content |
file |
File content |
resource |
Resource content |
... |
Mutliple |
type |
Type of the content |
is_error |
Whether the response is an error |
Use response_item to create a custom response item.
A response object
response( response_text("Hello, world!"), response_image(system.file("extdata/logo.png", package = "mcpr")), response_audio(system.file("extdata/sound.mp3", package = "mcpr")), response_video(system.file("extdata/video.mp4", package = "mcpr")), response_file(system.file("extdata/file.txt", package = "mcpr")), response_resource(system.file("extdata/resource.json", package = "mcpr")) )response( response_text("Hello, world!"), response_image(system.file("extdata/logo.png", package = "mcpr")), response_audio(system.file("extdata/sound.mp3", package = "mcpr")), response_video(system.file("extdata/video.mp4", package = "mcpr")), response_file(system.file("extdata/file.txt", package = "mcpr")), response_resource(system.file("extdata/resource.json", package = "mcpr")) )
Generate MCP server output
## S3 method for class 'roclet_mcp' roclet_output(x, results, base_path, ...)## S3 method for class 'roclet_mcp' roclet_output(x, results, base_path, ...)
x |
MCP roclet object |
results |
List of processed tools |
base_path |
Base path |
... |
Additional arguments |
NULL (invisible)
Process blocks for MCP roclet
## S3 method for class 'roclet_mcp' roclet_process(x, blocks, env, base_path)## S3 method for class 'roclet_mcp' roclet_process(x, blocks, env, base_path)
x |
MCP roclet object |
blocks |
List of roxy_block objects |
env |
Environment |
base_path |
Base path |
List of processed MCP tools
Parses @mcp tags to extract tool name and description.
## S3 method for class 'roxy_tag_mcp' roxy_tag_parse(x)## S3 method for class 'roxy_tag_mcp' roxy_tag_parse(x)
x |
A roxy_tag object |
Parses @type tags to extract parameter type information. Format: @type param_name type enum_values
## S3 method for class 'roxy_tag_type' roxy_tag_parse(x)## S3 method for class 'roxy_tag_type' roxy_tag_parse(x)
x |
A roxy_tag object |
Roxygen2 tag for @mcp This function is called by Roxygen2 to generate documentation for the @mcp tag
## S3 method for class 'roxy_tag_mcp' roxy_tag_rd(x, base_path, env)## S3 method for class 'roxy_tag_mcp' roxy_tag_rd(x, base_path, env)
x |
Roxygen2 tag object |
base_path |
Base path for the package |
env |
Environment |
NULL (invisible)
Roxygen2 tag handler for @type This function is called by Roxygen2 to generate documentation for the @type
## S3 method for class 'roxy_tag_type' roxy_tag_rd(x, base_path, env)## S3 method for class 'roxy_tag_type' roxy_tag_rd(x, base_path, env)
x |
Roxygen2 tag object |
base_path |
Base path for the package |
env |
Environment |
NULL (invisible)
Create a new input schema
schema(properties, type = "object", additional_properties = FALSE)schema(properties, type = "object", additional_properties = FALSE)
properties |
List of property definitions created with properties() |
type |
Type of the schema (default: "object") |
additional_properties |
Whether additional properties are allowed |
A list representing a JSON Schema object
schema <- schema( properties = properties( name = property_string("User name", "The name of the user", required = TRUE), age = property_number("User age", "The age of the user in years", minimum = 0) ) )schema <- schema( properties = properties( name = property_string("User name", "The name of the user", required = TRUE), age = property_number("User age", "The age of the user in years", minimum = 0) ) )
Serve an MCP server over HTTP using ambiorix
serve_http(mcp, port = Sys.getenv("SHINY_PORT", 3000), path = "/mcp")serve_http(mcp, port = Sys.getenv("SHINY_PORT", 3000), path = "/mcp")
mcp |
An MCP server object |
port |
Port to listen on, defaults to 3000 |
path |
Path to serve the MCP endpoint, defaults to "/mcp" |
Invisible, runs indefinitely
Serve an MCP server using stdin/stdout
serve_io(mcp)serve_io(mcp)
mcp |
An MCP server object created with new_server() |
Nothing, runs indefinitely in normal mode, or the response in test mode
Call a tool with the given parameters
tools_call(mcp, params, id = NULL)tools_call(mcp, params, id = NULL)
mcp |
A server object |
params |
Parameters for the tool call |
id |
Optional request ID for response tracking |
A response object with the tool call results or an error
List all available tools
tools_list(mcp)tools_list(mcp)
mcp |
A server object |
A list containing all available tools
Write a JSON-RPC request to a client provider
write(x, method, params = NULL, id = generate_id(), timeout = 5000)write(x, method, params = NULL, id = generate_id(), timeout = 5000)
x |
A client provider |
method |
The method to call |
params |
The parameters to pass to the method |
id |
The id of the request |
timeout |
Timeout in milliseconds for reading the response |
The client provider