mcp_endpoint() returns a Shiny app that answers MCP requests at path
(default /mcp), so an MCP App can be deployed anywhere Shiny apps run:
Posit Connect, Shiny Server, or shiny::runApp() on your own machine.
Deploy it like any Shiny app, then point MCP clients at
https://<server>/<app-path>/mcp.
Given an McpApp (or a list of them), browsers visiting the app get the same preview page as
preview_app().Given a Shiny app and
apps, browsers get the Shiny app and MCP clients get the apps. One deployment serves people and models; the apps can share the Shiny app's UI and functions.Given a Shiny app alone, browsers still get the Shiny app, and the endpoint serves it, live, to MCP clients through
as_mcp_app().
Clients that speak the stateless MCP revision (2026-07-28) can reach
any of several R processes behind a load balancer. Live Shiny apps keep
each view's session in the process that opened it; see as_mcp_app()
for what happens when a request lands elsewhere.
On Posit Connect the endpoint sits behind the content's access controls,
and mcp_request() reports the signed-in user.
Usage
mcp_endpoint(
x,
apps = NULL,
path = "/mcp",
allowed_origins = NULL,
allowed_hosts = NULL,
preview = TRUE,
...
)Arguments
- x
An McpApp, a list of apps, or a Shiny app.
- apps
When
xis a Shiny app, the apps to serve to MCP clients next to it: an McpApp or a list of them. Withoutapps, the Shiny app itself is served, live.- path
Endpoint path.
- allowed_origins
Browser origins, besides the app's own, allowed to call the endpoint. See
serve().- allowed_hosts
Host names the app is reached at, when it runs somewhere other than Posit Connect, shinyapps.io, or Shiny Server (for example in a container behind your own proxy). Elsewhere, requests for host names other than
localhostor an IP address are refused; seeserve().- preview
For apps, whether browsers get a preview page at
/.- ...
Passed to
as_mcp_app()whenxis a Shiny app served live.
Shiny's own MCP support
Shiny is gaining MCP support of its own
(https://github.com/rstudio/shiny/pull/4407). Once it is released, it
will be the way to put a live Shiny app in a chat, and shinymcp will stop
serving live apps. as_mcp_app(), mcp_endpoint(), and
mcp_tool_module() will take only apps built from tools, and bindMcp()
and the helpers for server functions (mcp_model_context(),
mcp_host_context(), and the rest) will be removed. For something the
model should be able to use on its own, rewrite that part of the app as
tools with mcp_app(); see vignette("rewriting-as-tools").
See also
Other serving:
preview_app(),
serve(),
shinymcp-options
Examples
if (FALSE) { # \dontrun{
# app.R, deployed to Posit Connect with rsconnect::deployApp()
library(shinymcp)
app <- mcp_app(ui, tools = list(summarize_dataset), name = "datasets")
mcp_endpoint(app)
# A Shiny app for people, and an app built from tools for chat clients
library(shiny)
shinyApp(ui, server) |> mcp_endpoint(apps = app)
# A Shiny app, served live to chat clients and as usual to browsers
shinyApp(ui, server) |> mcp_endpoint(name = "explorer")
} # }
