Skip to content

MCP Server Part 2: Represent callback-related data with a CallbackAdapter - #3711

Merged
KoolADE85 merged 6 commits into
mcpfrom
feature/mcp-callback-adapters
Apr 16, 2026
Merged

MCP Server Part 2: Represent callback-related data with a CallbackAdapter#3711
KoolADE85 merged 6 commits into
mcpfrom
feature/mcp-callback-adapters

Conversation

@KoolADE85

@KoolADE85KoolADE85 commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add CallbackAdapter: wraps a Dash callback and exposes MCP-related metadata (computed lazily)
    • It combines Dash's own callback map, layout, and user docstrings/types into 1 interface that the MCP server will use to present a complete picture of the app to LLMs.
  • Add CallbackAdapterCollection for working with collections of adapters
  • Add mcp_enabled parameter to @app.callback() for opting callbacks out of MCP
  • Add mcp>=1.0.0 to dependencies

Manual testing

  • You can inspect what kind of data the CallbackAdapter exposes
  • you can run callbacks directly with run_callback (which is what MCP will do)
fromdashimportDash, html, dcc, Input, Outputfromdash._get_appimportapp_contextapp=Dash(__name__)
app.layout=html.Div([
dcc.Input(id="name", value="World"),
html.Div(id="greeting"),
])
@app.callback(Output("greeting", "children"), Input("name", "value"))defgreet(name):
"""Greet the user by name."""returnf"Hello, {name}!"withapp.server.app_context():
app_context.set(app)
fromdash.mcp.primitives.tools.callback_adapter_collectionimportCallbackAdapterCollectionfromdash.mcp.primitives.tools.callback_utilsimportrun_callbackcollection=CallbackAdapterCollection(app)
foradapterincollection:
print(f"Tool: {adapter.tool_name}")
print(f" Docstring: {adapter._docstring}")
print(f" Outputs: {[o['id_and_prop'] foroinadapter.outputs]}")
print(f" Inputs: {[i['name'] foriinadapter.inputs]}")
# Execute the callback through the adapteradapter=collection[0]
result=run_callback(adapter, {"name": "Alice"})
print(f"Callback result: {result}")

@github-actions

github-actionsBot commented Apr 1, 2026

Copy link
Copy Markdown

Thank you for your contribution to Dash! 🎉

This PR is exempt from requiring a linked issue due to its labels.

@KoolADE85
KoolADE85force-pushed the feature/mcp-callback-adapters branch 2 times, most recently from 42aa12d to 0334a96CompareApril 1, 2026 22:45
@KoolADE85
KoolADE85force-pushed the feature/mcp-callback-adapters branch 2 times, most recently from c6cbe97 to cd073cfCompareApril 6, 2026 18:11
@KoolADE85
KoolADE85 changed the base branch from feature/mcp-framework-foundations to mcpApril 8, 2026 15:57
Comment threaddash/mcp/primitives/tools/callback_adapter.py Outdated
Comment threaddash/mcp/primitives/tools/callback_adapter.py Outdated
Comment threaddash/mcp/primitives/tools/callback_adapter.py Outdated
Comment threaddash/mcp/primitives/tools/callback_adapter.py Outdated
Comment threaddash/mcp/primitives/tools/callback_adapter.py Outdated
return None


def _coerce_value(value: Any) -> Any:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could add a generic here [TInput, TOutput]

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even better: this function wasn't really needed anymore as most usages had been refactored away. I just refactored its last remaining user and this function is now removed.

Comment threaddash/mcp/types/exceptions.py Outdated
class CallbackExecutionError(MCPError):
"""Callback raised an exception during execution."""

code = -32603

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are these code? This one has the same code as the base MCPError

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are standard JSON-RPC error codes, as per the MCP spec on error handling.
I removed the redundant one.

@T4rk1nT4rk1n left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💃

@KoolADE85
KoolADE85 merged commit 65281a1 into mcpApr 16, 2026
16 of 17 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@KoolADE85@T4rk1n@camdecoster