fix(mcp): Validate required tool args and fix title fallback for existing blocks

Backend: Add required-field validation in MCPToolBlock.run() before
calling the MCP server. The executor-level validation is bypassed for
MCP blocks because get_input_defaults() flattens tool_arguments,
stripping tool_input_schema from the validation context.

Frontend: NodeHeader now derives the MCP server label from the server
URL hostname when server_name is missing (pruned by pruneEmptyValues).
This fixes the title for existing blocks that don't have customized_name
in metadata.
This commit is contained in:
Zamil Majdy
2026-02-10 15:42:51 +04:00
parent 4d4ed562f0
commit 4364a771d4
2 changed files with 29 additions and 1 deletions

View File

@@ -260,6 +260,20 @@ class MCPToolBlock(Block):
yield "error", "No tool selected. Please select a tool from the dropdown."
return
# Validate required tool arguments before calling the server.
# The executor-level validation is bypassed for MCP blocks because
# get_input_defaults() flattens tool_arguments, stripping tool_input_schema
# from the validation context.
required = set(input_data.tool_input_schema.get("required", []))
if required:
missing = required - set(input_data.tool_arguments.keys())
if missing:
yield "error", (
f"Missing required argument(s): {', '.join(sorted(missing))}. "
f"Please fill in all required fields marked with * in the block form."
)
return
# If no credentials were injected by the executor (e.g. legacy nodes
# that don't have the credentials field set), try to auto-lookup
# the stored MCP credential for this server URL.

View File

@@ -25,10 +25,24 @@ export const NodeHeader = ({ data, nodeId }: Props) => {
data.block_id === SpecialBlockID.MCP_TOOL &&
!!data.hardcodedValues?.selected_tool;
// Derive MCP server label: prefer server_name, fall back to URL hostname.
let mcpServerLabel = "MCP";
if (isMCPWithTool) {
mcpServerLabel =
data.hardcodedValues.server_name ||
(() => {
try {
return new URL(data.hardcodedValues.server_url).hostname;
} catch {
return "MCP";
}
})();
}
const title =
(data.metadata?.customized_name as string) ||
(isMCPWithTool
? `${data.hardcodedValues.server_name || "MCP"}: ${beautifyString(data.hardcodedValues.selected_tool)}`
? `${mcpServerLabel}: ${beautifyString(data.hardcodedValues.selected_tool)}`
: null) ||
data.hardcodedValues?.agent_name ||
data.title;