Skip to content

Implement configuration function to customize MCP server#3796

Open
KoolADE85 wants to merge 3 commits into
mcpfrom
feature/mcp-configuration-function
Open

Implement configuration function to customize MCP server#3796
KoolADE85 wants to merge 3 commits into
mcpfrom
feature/mcp-configuration-function

Conversation

@KoolADE85
Copy link
Copy Markdown
Contributor

This PR adds a function to configure the MCP server behaviour:

Rather than add a growing list of constructor args around the MCP server, this PR implements a single configure_mcp_server() function that allows users to toggle various parts of the server with arguments:

def configure_mcp_server(
    *,
    include_layout: bool = True,
    include_callbacks: bool = True,
    include_clientside_callbacks: bool = True,
    include_pages: bool = True,
    expose_callback_docstrings: bool = False,
) -> None:

The existing mcp_expose_docstrings constructor arg has been removed and replaced by this function.

@camdecoster camdecoster self-assigned this May 28, 2026
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

@camdecoster camdecoster left a comment

Choose a reason for hiding this comment

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

I left a couple of suggestions, but nothing huge. Could you add a changelog entry for this update? Specifically describing the way the user facing API changed.

Comment thread dash/mcp/_configure.py
Comment on lines +75 to +82
if not include_layout:
updated_resources.remove(LayoutResource)
updated_resources.remove(ComponentsResource)
if not include_clientside_callbacks:
updated_resources.remove(ClientsideCallbacksResource)
if not include_pages:
updated_resources.remove(PagesResource)
updated_resources.remove(PageLayoutResource)
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 do you think of creating lists to keep things tidy? Something like this:

LAYOUT_RESOURCES = [ComponentsResource, LayoutResource]
if not include_layout:
  updated_resources.remove(item) for item in LAYOUT_RESOURCES

Comment thread dash/mcp/_configure.py
updated_tools.remove(GetDashComponentTool)
MCP_TOOL_PROVIDERS[:] = updated_tools

get_app().mcp_callback_map = None
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.

Do you need to wrap this in a try/except block too?

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.

Do you need to reset MCP_DECORATED_FUNCTIONS like you do in tests/unit/mcp/conftest.py?

app_context.set(app)
if MCP_DECORATED_FUNCTIONS:
    app.mcp_decorated_functions = dict(MCP_DECORATED_FUNCTIONS)
    MCP_DECORATED_FUNCTIONS.clear()

Comment thread dash/mcp/_configure.py
Comment on lines +38 to +39
Any parameter that is omitted will be reset to its default value. Calling
with no args will reset all configuration to its default state.
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.

IMO, it seems safer to only mutate the config values when they're specifically passed in. On first call they get set with defaults or the provided values, then subsequent calls only update the specific values passed in.

Comment thread dash/dash.py
self._callback_list: list = []
self.callback_api_paths: dict = {}
self.mcp_decorated_functions: dict = {}
self.mcp_callback_map: Any = None
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.

Suggested change
self.mcp_callback_map: Any = None
self.mcp_callback_map: Optional["CallbackAdapterCollection"] = None

Comment thread dash/mcp/_configure.py
if get_app().backend.has_request_context():
raise RuntimeError("MCP server can't be configured within a callback")
except AppNotFoundError:
...
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.

Suggested change
...
pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants