Callbacks as MCP Tools

By default, all callbacks are exposed as MCP tools when the MCP server is enabled. This means that AI agents can see, understand, and trigger your callbacks.

What Is Automatically Surfaced to Agents

When a callback is enabled for MCP, its Inputs, Outputs, and State are all described in-depth to the AI agent. The MCP server analyzes the relationship between your callbacks and your layout, revealing how they are linked together. Consider the following example:

app.layout = html.Div([
    html.Label("Select a number", htmlFor="dd"),
    dcc.Dropdown(id="dd", options=[1,2,3], value=2),
    html.P(id="result")
])

@callback(
    Output("result", "children"),
    Input("dd", "value"),
)
def select_value(value: int):
  return f"You selected {value}"

The MCP server will reveal the following facts about the callback:
* its name is select_value
* it accepts an int input whose value can be 1, 2, or 3
* its default input value is 2
* its input is labelled with the text “Select a number”
* it outputs children to the “result” component
* its default output value is “You selected 2”

Understanding what’s surfaced can help you decide which callbacks to expose and how much extra context to provide — both covered below.

Excluding and Selecting Callbacks

You can exclude individual callbacks by setting mcp_enabled=False on the individual callback:

@callback(Output(...), Input(...), mcp_enabled=False)
def callback():
    """This callback will not be visible or accessible to AI agents"""

Opting In Instead of Out

If you’d rather expose only a hand-picked set of callbacks, flip the default with configure_mcp_server:

from dash.mcp import configure_mcp_server

configure_mcp_server(include_callbacks=False)

With include_callbacks=False, no callback is exposed unless you explicitly opt it in with mcp_enabled=True:

@callback(Output(...), Input(...), mcp_enabled=True)
def callback():
    """Only this callback is visible to AI agents."""

Whichever default you choose, the per-callback mcp_enabled setting always takes precedence. (mcp_enabled cannot enable any callback when the MCP server itself is off — set enable_mcp=True on the Dash constructor first.)

Customizing How AI Agents See Your Callbacks

AI agents fundamentally see callbacks the same way that users see them in their browser: as layout components acting as Inputs, Outputs and/or State for your callback function.

Beyond what is automatically described, you can customize portions to provide further context for AI agents.

Type Annotations

The type of most arguments varies. For example, dropdown options accept strings, numbers, or booleans (even if your dropdown only uses one of those types). The MCP server, by default, tells AI agents about the broad range of types, and they infer the best type to send to your callback through context and trial-and-error.

When you annotate your callback arguments with an exact type, the MCP server tells AI agents about this annotation so that they always send valid data. For example, annotating the value as follows causes AI agents to always send lists of numbers rather than attempting strings:

@callback(Output(...), Input(...))
def callback(value: List[int])

We recommend annotating your callback arguments wherever the type is known. Precise annotations make agents better at communicating with your app and less prone to errors, and they avoid the wasted tokens and round-trips that come from trial-and-error.

Docstrings

By default, docstrings are not exposed to AI agents. You can opt to include the docstring by adding mcp_expose_docstring=True as a callback argument.
When this parameter is enabled, your callback’s docstring are included verbatim as additional descriptive context.

This allows you to:

Alternatively, you can call configure_mcp_server(expose_callback_docstrings=True) to include docstrings for every callback. Then, opt-out docstrings per-callback with mcp_expose_docstring=False.

from dash.mcp import configure_mcp_server

configure_mcp_server(expose_callback_docstrings=True)

Note: The parameter is plural (expose_callback_docstrings) on configure_mcp_server(), since it controls every callback’s docstring, and singular (mcp_expose_docstring) on an individual @callback, since it controls just that one. The per-callback setting takes precedence over the app-wide default.

Special Return Values

If your callback returns a plotly figure, the MCP server will attempt to render it as a PNG image using Kaleido for agents that support displaying images. If you do not have Kaleido installed in your environment, this step will be skipped.

If your callback returns a dataframe, the MCP server will attempt to render it as a Markdown table for agents that support displaying tables.