| Title: | Model Context Protocol Server Derived from 'tidybrreg' |
|---|---|
| Description: | Exposes the exported functions of 'tidybrreg' as Model Context Protocol (MCP) tools. The tool catalogue, every tool's title, description, argument documentation and input schema are derived at run time from the installed 'tidybrreg' namespace and its help pages, so the server changes exactly when 'tidybrreg' changes and adds no interpretation of the register's data of its own: tools return the tibbles 'tidybrreg' returns, with its column names, its codes, its attributes and its typed conditions. Serves over standard streams or streamable HTTP. |
| Authors: | Sondre Skarsten [aut, cre] |
| Maintainer: | Sondre Skarsten <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.6.0 |
| Built: | 2026-11-03 08:18:34 UTC |
| Source: | https://github.com/sondreskarsten/tidybrreg |
Pure dispatcher shared by every transport. Requests return a response
object; notifications return NULL. Tool execution errors are
reported inside the result (isError), protocol errors as JSON-RPC
errors.
mcp_handle(srv, msg)mcp_handle(srv, msg)
srv |
Server state from |
msg |
A decoded JSON-RPC message (named list). |
A named list (the response) or NULL.
srv <- mcp_server() mcp_handle(srv, list(jsonrpc = "2.0", id = 1, method = "ping"))srv <- mcp_server() mcp_handle(srv, list(jsonrpc = "2.0", id = 1, method = "ping"))
Serialises everything a server needs to expose tidybrreg over the
Model Context Protocol without running R: the tool catalogue of
mcp_tools() (titles, descriptions, input and output schemas), the
machine-readable endpoint contract shipped by tidybrreg
(inst/extdata/endpoints.json, tested against the functions), the
bundled dictionaries with their vintages, every help topic as
Markdown, and the server instructions. The output is deterministic
for a given installed tidybrreg (no timestamps), so the Node
implementation in tidybrreg-mcp-node/ commits it and CI fails when
regenerating it changes anything: the non-R server changes exactly
when tidybrreg does.
mcp_manifest( path = "tidybrreg-mcp-manifest.json", package = "tidybrreg", exclude = character() )mcp_manifest( path = "tidybrreg-mcp-manifest.json", package = "tidybrreg", exclude = character() )
path |
File to write. |
package |
Package whose exports become tools. Only |
exclude |
Character vector of export names not to expose. Defaults
to the comma-separated |
The manifest as a list, invisibly when path is given.
m <- mcp_manifest(NULL) names(m) length(m$tools)m <- mcp_manifest(NULL) names(m) length(m$tools)
Starts an MCP server whose tools are tidybrreg's exported functions
(see mcp_tools()). Two transports are available.
mcp_serve( transport = c("stdio", "http"), host = "0.0.0.0", port = as.integer(Sys.getenv("PORT", "8080")), token = Sys.getenv("MCP_BEARER_TOKEN", ""), srv = NULL )mcp_serve( transport = c("stdio", "http"), host = "0.0.0.0", port = as.integer(Sys.getenv("PORT", "8080")), token = Sys.getenv("MCP_BEARER_TOKEN", ""), srv = NULL )
transport |
|
host, port
|
Bind address for the HTTP transport. |
token |
Bearer token for the HTTP transport; |
srv |
Server state; built with |
mcp_serve() runs until the client closes the connection
(stdio) or the process is interrupted (HTTP) and then returns
invisible(NULL).
transport = "stdio" reads newline-delimited JSON-RPC messages from
standard input and writes responses to standard output, which is what
desktop clients (Claude Desktop, Claude Code, Cursor, ...) expect
from a locally launched server. Log lines go to standard error. A
client configuration is:
{"mcpServers": {"tidybrreg": {"command": "Rscript",
"args": ["-e", "tidybrregmcp::mcp_serve()"]}}}
transport = "http" serves the streamable HTTP transport with
httpuv: POST /mcp carries one JSON-RPC message (or a batch) and
answers with application/json; GET /mcp answers 405 because this
server never pushes messages; DELETE /mcp ends a session;
GET /health reports the server and the tidybrreg version. When the
MCP_BEARER_TOKEN environment variable (or token) is set, every
/mcp request must carry it as Authorization: Bearer.
## Not run: tidybrregmcp::mcp_serve() tidybrregmcp::mcp_serve("http", port = 8080) ## End(Not run)## Not run: tidybrregmcp::mcp_serve() tidybrregmcp::mcp_serve("http", port = 8080) ## End(Not run)
Builds the tool catalogue and resource index from the installed
tidybrreg once; transports call mcp_handle() with it for every
message.
mcp_server(package = "tidybrreg", exclude = mcp_excluded())mcp_server(package = "tidybrreg", exclude = mcp_excluded())
package |
Package whose exports become tools. Only |
exclude |
Character vector of export names not to expose. Defaults
to the comma-separated |
An environment holding tools, resources, info,
instructions, and initialized.
srv <- mcp_server() length(srv$tools)srv <- mcp_server() length(srv$tools)
Every exported function of tidybrreg becomes one tool. The tool's title, description and argument documentation are rendered from the function's installed help page, the input schema is inferred from the function's formals together with the documented argument types, and nothing is hand-written per tool. A change to tidybrreg's exports or documentation changes the catalogue the next time the server starts.
mcp_tools(package = "tidybrreg", exclude = mcp_excluded())mcp_tools(package = "tidybrreg", exclude = mcp_excluded())
package |
Package whose exports become tools. Only |
exclude |
Character vector of export names not to expose. Defaults
to the comma-separated |
A named list of tool definitions, each a list with name,
title, description, inputSchema, outputSchema,
annotations, and (not sent to clients) fn and arg_info.
Four optional arguments that tidybrreg does not have are added to every tool by the server, all prefixed with a dot so they can never collide with a tidybrreg argument:
.limit: maximum rows returned (default 200, at most
getOption("tidybrregmcp.max_rows", 5000)).
.offset: rows to skip before returning (default 0).
.columns: column names to keep, in tidybrreg's English names.
.format: "records" (default, JSON objects), "csv", or
"markdown" for the text rendering of the rows.
The structured result always reports the total row count so a caller
knows when it saw a slice.
tools <- mcp_tools() names(tools) tools$brreg_entity$inputSchema$properties$registrytools <- mcp_tools() names(tools) tools$brreg_entity$inputSchema$properties$registry