Uh oh!
There was an error while loading. Please reload this page.
MCP Server Part 8: MCP server routes - #3750
Conversation
Thank you for your contribution to Dash! 🎉 This PR is exempt from requiring a linked issue due to its labels. |
876285b to
43c15b2Comparechgiesse
commented
Apr 20, 2026
Hi Plotly team! First of all, thanks for integrating MCP into Dash - this looks really exciting!
Let me know what you think - if you see it the same way or if I overlooked something! Would also love to contribute these changes :) Best regards, |
8c1f392 to
f9b05daCompare43c15b2 to
f03c72fCompareKoolADE85
commented
Apr 22, 2026
Hey @chgiesse Thanks for the comments, and happy to see the excitement around the feature!
And absolutely, I'd welcome any contributions you have towards this effort - there's tons of potential to make Dash apps even more LLM friendly! Adrian |
f9b05da to
bc340e6Compared3e1e19 to
976e0dfComparebc340e6 to
b3d4015Compare20d3ee7 to
bb25991Compareb3d4015 to
e407569Comparebb25991 to
9cc9959Comparee407569 to
37e92f0Compare9cc9959 to
e84d208Compare37e92f0 to
28d5fedComparee84d208 to
943d9b2CompareHi @KoolADE85 Thanks for the response and making it compatible! Looking forward to use it! Yes I also think that the functionality without sse is already a good starting point. Maybe providing it together with a native sse callback? :) |
28d5fed to
f098f88Compareac43cd0 to
8d7b8baComparef098f88 to
79df12eComparee0662fc to
3c39eacComparef1b6cc2 to
d25123bCompare3c39eac to
a1ca057Comparea1ca057 to
409be55Compare…0 for missing session)
409be55 to
b788678Compare| [ | ||
| { | ||
| "id": str(comp.id), | ||
| "id": str(getattr(comp, "id", None)), |
There was a problem hiding this comment.
Doesn't line 49 guarantee that id exists?
| if pattern is None: | ||
| return None | ||
| matches = find_matching_components(pattern) |
There was a problem hiding this comment.
| ifpatternisNone: | |
| returnNone | |
| matches=find_matching_components(pattern) | |
| matches=find_matching_components(pattern) ifpatternelseNone |
There was a problem hiding this comment.
This one was actually necessary for the linter too.
| dep: CallbackDependency, value: Any | ||
| ) -> CallbackInput | list[CallbackInput]: | ||
| def _expand_dep(dep: CallbackDependency, value: Any) -> CallbackInputs: | ||
| """Attach a concrete value to a callback dependency to produce a valid callback input. |
There was a problem hiding this comment.
Claude 😠!
| """Attachaconcretevaluetoacallbackdependencytoproduceavalidcallbackinput. | |
| """ | |
| Attachaconcretevaluetoacallbackdependencytoproduceavalidcallbackinput. |
| concrete_ids = [comp.id for comp in find_matching_components(pattern)] | ||
| expanded = [{"id": cid, "property": prop} for cid in concrete_ids] | ||
| concrete_ids = [ | ||
| getattr(comp, "id") for comp in find_matching_components(pattern) |
There was a problem hiding this comment.
It cannot be None since find_matching_components only returns pattern-matching components (i.e. id is a dict), so getattr(comp, "id") is always a dict.
| if func is not None: | ||
| return _wrap(func) | ||
| return _wrap |
There was a problem hiding this comment.
Do you need to return the wrapping function here?
There was a problem hiding this comment.
This is because the decorator supports optional arguments:
func is None when used with arguments (@mcp_enabled(name="foo"))
It's not None when used bare (@mcp_enabled)
| app.mcp_decorated_functions = dict(MCP_DECORATED_FUNCTIONS) | ||
| MCP_DECORATED_FUNCTIONS.clear() | ||
| _session_id: str | None = None |
There was a problem hiding this comment.
Could you look into what would happen to this value if multiple users attempt to connect at the same time? Would some users end up with the wrong session id? It's a classic TOCTOU race condition 🙄.
Could multiple gunicorn works get there own session id? You mentioned this during our review.
5df8628 to
7f06fd7Compare750c20e to
ca9146eCompareUh oh!
There was an error while loading. Please reload this page.
Summary
This PR pulls together everything from the previous PRs into a working MCP server you can connect to from any MCP-compatible LLM agent. Example:
enable_mcpandmcp_pathconstructor params, (orDASH_MCP_ENABLED/DASH_MCP_PATHenv vars)