MCP Server Part 7: get_dash_component tool and callback tool execution#3749
MCP Server Part 7: get_dash_component tool and callback tool execution#3749
get_dash_component tool and callback tool execution#3749Conversation
|
Thank you for your contribution to Dash! 🎉 This PR is exempt from requiring a linked issue due to its labels. |
0e54d74 to
8a41b76
Compare
8c1f392 to
f9b05da
Compare
8a41b76 to
4fb9d4a
Compare
f9b05da to
bc340e6
Compare
4fb9d4a to
10a544b
Compare
bc340e6 to
b3d4015
Compare
d203cf9 to
e73cd17
Compare
e407569 to
37e92f0
Compare
2acb39d to
04ca2fe
Compare
37e92f0 to
28d5fed
Compare
04ca2fe to
8f9d5a0
Compare
f098f88 to
79df12e
Compare
camdecoster
left a comment
There was a problem hiding this comment.
I made a few suggestions. The one to pay attention to is the loop going through callbacks/inputs/outputs. Let me know what you think.
| if prop_filter and prop_name != prop_filter: | ||
| continue | ||
|
|
||
| value = callback_map.get_initial_value(f"{comp_id}.{prop_name}") |
There was a problem hiding this comment.
| value = callback_map.get_initial_value(f"{comp_id}.{prop_name}") | |
| id_and_prop = f"{comp_id}.{prop_name}" | |
| value = callback_map.get_initial_value(id_and_prop) |
|
|
||
| modified_by: list[str] = [] | ||
| input_to: list[str] = [] | ||
| id_and_prop = f"{comp_id}.{prop_name}" |
There was a problem hiding this comment.
| id_and_prop = f"{comp_id}.{prop_name}" |
| def call_tool(cls, tool_name: str, arguments: dict[str, Any]) -> CallToolResult: | ||
| comp_id = arguments.get("component_id", "") | ||
| if not comp_id: | ||
| raise ValueError("component_id is required") |
There was a problem hiding this comment.
| raise ValueError("component_id is required") | |
| return CallToolResult( | |
| content=[TextContent(type="text", text="component_id is required")], | |
| isError=True, | |
| ) |
| if component is None: | ||
| callback_map = get_app().mcp_callback_map |
There was a problem hiding this comment.
| if component is None: | |
| callback_map = get_app().mcp_callback_map | |
| callback_map = get_app().mcp_callback_map | |
| if component is None: |
| isError=True, | ||
| ) | ||
|
|
||
| callback_map = get_app().mcp_callback_map |
There was a problem hiding this comment.
| callback_map = get_app().mcp_callback_map |
| for cb in callback_map: | ||
| for out in cb.outputs: | ||
| if out["id_and_prop"] == id_and_prop: | ||
| modified_by.append(cb.tool_name) | ||
| for inp in cb.inputs: | ||
| if inp["id_and_prop"] == id_and_prop: | ||
| input_to.append(cb.tool_name) |
There was a problem hiding this comment.
This could get expensive for apps with a lot of callbacks, inputs, outputs. Is there a way to create and use an index for looking this up?
There was a problem hiding this comment.
Great point! The dash renderer actually implements such a mapping (but in JS obviously). I'll do the same on the python side.
f1b6cc2 to
d25123b
Compare
Summary
Wires up the full tool pipeline following the same pattern as
resources:list_tools()builds the tool list from all registered tool providerscall_tool(name, args)routes LLM calls to the appropriate callback functionAdds a static tool
get_dash_componentwhich allows LLMs to query a specific prop for a given ID.Manual verification: