@@ -354,6 +354,12 @@ def create_client(
354354 Note: Authentication is handled by start.bat/start.sh before this runs.
355355 The Claude SDK auto-detects credentials from the Claude CLI configuration
356356 """
357+ # Cache UI config once to avoid repeated file reads
358+ # This is used for both allowed_tools and MCP server configuration
359+ ui_mcp_disabled = os .getenv ("DISABLE_UI_MCP" , "" ).lower () == "true"
360+ ui_config = None if ui_mcp_disabled else get_ui_config_from_spec (project_dir )
361+ has_ui_mcp = ui_config is not None and ui_config .get ("has_mcp" , False )
362+
357363 # Build allowed tools list based on mode
358364 # In YOLO mode, exclude Playwright tools for faster prototyping
359365 allowed_tools = [* BUILTIN_TOOLS , * FEATURE_MCP_TOOLS ]
@@ -362,10 +368,8 @@ def create_client(
362368
363369 # Add UI MCP tools if the project uses a library with MCP support
364370 # UI MCP is available in both standard and YOLO mode
365- if os .getenv ("DISABLE_UI_MCP" , "" ).lower () != "true" :
366- ui_config = get_ui_config_from_spec (project_dir )
367- if ui_config and ui_config .get ("has_mcp" ):
368- allowed_tools .extend (UI_MCP_TOOLS )
371+ if has_ui_mcp :
372+ allowed_tools .extend (UI_MCP_TOOLS )
369373
370374 # Build permissions list
371375 permissions_list = [
@@ -399,10 +403,8 @@ def create_client(
399403 permissions_list .extend (PLAYWRIGHT_TOOLS )
400404
401405 # Add UI MCP tools to permissions if available
402- if os .getenv ("DISABLE_UI_MCP" , "" ).lower () != "true" :
403- ui_config = get_ui_config_from_spec (project_dir )
404- if ui_config and ui_config .get ("has_mcp" ):
405- permissions_list .extend (UI_MCP_TOOLS )
406+ if has_ui_mcp :
407+ permissions_list .extend (UI_MCP_TOOLS )
406408
407409 # Create comprehensive security settings
408410 # Note: Using relative paths ("./**") restricts access to project directory
@@ -485,52 +487,50 @@ def create_client(
485487
486488 # UI Components MCP server (available in both standard and YOLO mode)
487489 # Only added for libraries with MCP support (shadcn-ui, ark-ui)
488- if os .getenv ("DISABLE_UI_MCP" , "" ).lower () != "true" :
489- ui_config = get_ui_config_from_spec (project_dir )
490- if ui_config and ui_config .get ("has_mcp" ):
491- library = ui_config .get ("library" , "" )
492- framework = ui_config .get ("framework" , "react" )
490+ if has_ui_mcp and ui_config :
491+ library = ui_config .get ("library" , "" )
492+ framework = ui_config .get ("framework" , "react" )
493493
494- try :
495- npx_cmd = get_npx_command ()
496-
497- if library == "shadcn-ui" :
498- # shadcn/ui MCP server for React components
499- # Uses GitHub API - benefits from GITHUB_PERSONAL_ACCESS_TOKEN for rate limits
500- ui_mcp_args = [
501- "-y" ,
502- "--prefer-offline" ,
503- f"@jpisnice/shadcn-ui-mcp-server@{ SHADCN_MCP_VERSION } " ,
504- "--framework" , framework ,
505- ]
506- ui_mcp_env = {}
507- github_token = os . getenv ( "GITHUB_PERSONAL_ACCESS_TOKEN" )
508- if github_token :
509- ui_mcp_env [ "GITHUB_TOKEN" ] = github_token
510-
511- mcp_servers [ "ui_components" ] = {
512- "command" : npx_cmd ,
513- "args " : ui_mcp_args ,
514- "env" : ui_mcp_env if ui_mcp_env else None ,
515- }
516- print (f" - UI MCP: shadcn/ui ({ framework } )" )
517-
518- elif library == "ark-ui" :
519- # Ark UI MCP server for multi-framework headless components
520- ui_mcp_args = [
521- "-y" ,
522- "--prefer-offline" ,
523- f"@ark-ui/mcp@{ ARK_MCP_VERSION } " ,
524- ]
525- mcp_servers ["ui_components" ] = {
526- "command" : npx_cmd ,
527- "args" : ui_mcp_args ,
528- }
529- print (f" - UI MCP: Ark UI ({ framework } )" )
530-
531- except RuntimeError as e :
532- # npx not found - graceful degradation
533- print (f" - Warning: UI MCP disabled - { e } " )
494+ try :
495+ npx_cmd = get_npx_command ()
496+
497+ if library == "shadcn-ui" :
498+ # shadcn/ui MCP server for React components
499+ # Uses GitHub API - benefits from GITHUB_PERSONAL_ACCESS_TOKEN for rate limits
500+ ui_mcp_args = [
501+ "-y" ,
502+ "--prefer-offline" ,
503+ f"@jpisnice/shadcn-ui-mcp-server@{ SHADCN_MCP_VERSION } " ,
504+ "--framework" , framework ,
505+ ]
506+ ui_mcp_config : dict = {
507+ "command" : npx_cmd ,
508+ "args" : ui_mcp_args ,
509+ }
510+ # Only add env if there are environment variables to pass
511+ github_token = os . getenv ( "GITHUB_PERSONAL_ACCESS_TOKEN" )
512+ if github_token :
513+ ui_mcp_config [ "env" ] = { "GITHUB_TOKEN " : github_token }
514+
515+ mcp_servers [ "ui_components" ] = ui_mcp_config
516+ print (f" - UI MCP: shadcn/ui ({ framework } )" )
517+
518+ elif library == "ark-ui" :
519+ # Ark UI MCP server for multi-framework headless components
520+ ui_mcp_args = [
521+ "-y" ,
522+ "--prefer-offline" ,
523+ f"@ark-ui/mcp@{ ARK_MCP_VERSION } " ,
524+ ]
525+ mcp_servers ["ui_components" ] = {
526+ "command" : npx_cmd ,
527+ "args" : ui_mcp_args ,
528+ }
529+ print (f" - UI MCP: Ark UI ({ framework } )" )
530+
531+ except RuntimeError as e :
532+ # npx not found - graceful degradation
533+ print (f" - Warning: UI MCP disabled - { e } " )
534534
535535 # Build environment overrides for API endpoint configuration
536536 # These override system env vars for the Claude CLI subprocess,
0 commit comments