246246 </div >
247247 </template >
248248 </NodeContainer >
249+ <McpServerInputDialog ref =" mcpServerInputDialogRef" @refresh =" handleMcpVariables" />
249250</template >
250251<script setup lang="ts">
251252import { cloneDeep , set } from ' lodash'
@@ -256,6 +257,7 @@ import { t } from '@/locales'
256257import { MsgError , MsgSuccess } from ' @/utils/message'
257258import TooltipLabel from ' @/components/dynamics-form/items/label/TooltipLabel.vue'
258259import NodeCascader from ' @/workflow/common/NodeCascader.vue'
260+ import McpServerInputDialog from " ./component/McpServerInputDialog.vue" ;
259261import { useRoute } from ' vue-router'
260262import { loadSharedApi } from ' @/utils/dynamics-api/shared-api'
261263import { resetUrl } from ' @/utils/common'
@@ -339,12 +341,22 @@ function getTools() {
339341 }
340342 try {
341343 JSON .parse (form_data .value .mcp_servers )
344+ const vars = extractPlaceholders (form_data .value .mcp_servers )
345+ if (vars .length > 0 ) {
346+ mcpServerInputDialogRef .value .open (vars )
347+ return
348+ }
342349 } catch (e ) {
343350 MsgError (t (' views.applicationWorkflow.nodes.mcpNode.mcpServerTip' ))
344351 return
345352 }
346- loadSharedApi ({ type: ' application' , systemType: apiType .value })
347- .getMcpTools (id , form_data .value .mcp_servers , loading )
353+ // 一切正常,获取tool
354+ _getTools (form_data .value .mcp_servers )
355+ }
356+
357+ function _getTools(mcp_servers : any ) {
358+ loadSharedApi ({ type: ' application' , systemType: apiType .value })
359+ .getMcpTools (id , mcp_servers , loading )
348360 .then ((res : any ) => {
349361 form_data .value .mcp_tools = res .data
350362 MsgSuccess (t (' views.applicationWorkflow.nodes.mcpNode.getToolsSuccess' ))
@@ -355,6 +367,47 @@ function getTools() {
355367 })
356368}
357369
370+ const mcpServerInputDialogRef = ref ()
371+ // 提取 JSON 中所有占位符({{...}})的变量路径
372+ function extractPlaceholders(input : unknown ): string [] {
373+ const re = / \{\{ \s * ([a-zA-Z _][\w. ] * )\s * \}\} / g ; // 捕获 {{ path.like.this }}
374+ const found = new Set <string >();
375+
376+ const visit = (v : unknown ) => {
377+ if (typeof v === ' string' ) {
378+ let m: RegExpExecArray | null ;
379+ while ((m = re .exec (v )) !== null ) found .add (m [1 ]);
380+ } else if (Array .isArray (v )) {
381+ v .forEach (visit );
382+ } else if (v && typeof v === ' object' ) {
383+ Object .values (v as Record <string , unknown >).forEach (visit );
384+ }
385+ };
386+
387+ // 如果传入的是 JSON 字符串,尝试解析,否则按字符串/对象处理
388+ if (typeof input === ' string' ) {
389+ try {
390+ visit (JSON .parse (input ));
391+ } catch {
392+ visit (input );
393+ }
394+ } else {
395+ visit (input );
396+ }
397+
398+ return [... found ];
399+ }
400+
401+ function handleMcpVariables(vars : any ) {
402+ let mcp_servers = form_data .value .mcp_servers
403+ for (const item in vars ) {
404+ mcp_servers = mcp_servers .replace (` {{${item }}} ` , vars [item ])
405+ }
406+
407+ // 一切正常,获取tool
408+ _getTools (mcp_servers )
409+ }
410+
358411function changeTool() {
359412 form_data .value .mcp_server = form_data .value .mcp_tools .find (
360413 (item : any ) => item .name === form_data .value .mcp_tool ,
0 commit comments