In a Shiny app served with as_mcp_app(), every input becomes an
argument of the app's tool and every output is reported to the model.
Mark some of them with bindMcp() and only the marked ones are: the
model gets a smaller tool that is easier to use well. The person using
the app still sees all of it.
ui <- fluidPage(
selectInput("species", "Species", species) |> bindMcp(),
sliderInput("alpha", "Point opacity", 0, 1, 0.7),
plotOutput("scatter") |> bindMcp(),
verbatimTextOutput("debug")
)Here the model can set the species and reads the plot; the opacity slider and the debug output stay between the app and its user. Action buttons are only pressed by the model when marked.
In a UI for mcp_app(), bindMcp() marks an element as an input or an
output of the app's tools when shinymcp can't tell on its own.
bindMcp() recognizes Shiny's and bslib's inputs and outputs, and
htmlwidget outputs. For anything else, give type. Marking an element
twice does nothing.
Usage
bindMcp(tag, ...)
# S3 method for class 'shiny.tag'
bindMcp(tag, id = NULL, type = NULL, ...)
# S3 method for class 'shiny.tag.list'
bindMcp(tag, id = NULL, type = NULL, ...)
# Default S3 method
bindMcp(tag, ...)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 apps:
McpApp,
as_mcp_app(),
mcp_app(),
mcp_tool_module()
Examples
shiny::selectInput("species", "Species", c("Adelie", "Gentoo")) |>
bindMcp()
#> <div class="form-group shiny-input-container">
#> <label class="control-label" id="species-label" for="species">Species</label>
#> <div>
#> <select id="species" class="shiny-input-select" data-shinymcp-input="species"><option value="Adelie" selected>Adelie</option>
#> <option value="Gentoo">Gentoo</option></select>
#> <script type="application/json" data-for="species" data-nonempty="">{"plugins":["selectize-plugin-a11y"]}</script>
#> </div>
#> </div>
