@@ -517,7 +517,7 @@ function runRecipeTool(server: McpServer) {
517517 {
518518 description : "Execute a built-in ethora-help recipe by id (sequential steps, no shell, no file writes)." ,
519519 inputSchema : {
520- recipeId : z . string ( ) . min ( 1 ) ,
520+ recipeId : z . string ( ) . min ( 1 ) . optional ( ) . describe ( "Recipe id. If omitted, lists runnable recipes for the selected goal." ) ,
521521 goal : z . enum ( [ "auto" , "b2b-bootstrap-ai" , "broadcast" , "sources-ingest" , "files-upload" , "bot-manage" , "user-login" ] ) . optional ( )
522522 . describe ( "Optional goal scope to look up recipes; defaults to auto." ) ,
523523 vars : z . record ( z . any ( ) ) . optional ( ) . describe ( "Variables to substitute (appId, appToken, b2bToken, appJwt, email, password, apiUrl, etc)." ) ,
@@ -536,12 +536,15 @@ function runRecipeTool(server: McpServer) {
536536 // Minimal subset of recipes: these IDs match ethora-help.
537537 const out : any = { recipes : [ ] as any [ ] }
538538 const apiUrl = String ( state . apiUrl || "https://api.ethoradev.com/v1" )
539- if ( effectiveGoal === "b2b-bootstrap-ai" ) {
539+ const includeAll = effectiveGoal === "auto"
540+
541+ if ( includeAll || effectiveGoal === "b2b-bootstrap-ai" ) {
540542 out . recipes . push (
541543 {
542544 id : "b2b-bootstrap-ai" ,
543545 title : "B2B bootstrap: create app → ingest → enable bot" ,
544546 description : "Best for partner automation and repeatable provisioning." ,
547+ requiredVars : [ "b2bToken" ] ,
545548 steps : [
546549 { tool : "ethora-configure" , args : { apiUrl, b2bToken : "<B2B_TOKEN>" } } ,
547550 { tool : "ethora-auth-use-b2b" } ,
@@ -552,6 +555,7 @@ function runRecipeTool(server: McpServer) {
552555 id : "b2b-create-app-only" ,
553556 title : "B2B: create app only" ,
554557 description : "Create an app via B2B token (no sources/bot)." ,
558+ requiredVars : [ "b2bToken" ] ,
555559 steps : [
556560 { tool : "ethora-configure" , args : { apiUrl, b2bToken : "<B2B_TOKEN>" } } ,
557561 { tool : "ethora-auth-use-b2b" } ,
@@ -560,11 +564,12 @@ function runRecipeTool(server: McpServer) {
560564 }
561565 )
562566 }
563- if ( effectiveGoal === "broadcast" ) {
567+ if ( includeAll || effectiveGoal === "broadcast" ) {
564568 out . recipes . push ( {
565569 id : "broadcast-v2" ,
566570 title : "Broadcast to chat rooms (v2 job)" ,
567571 description : "Select app + appToken, switch to app auth, enqueue broadcast, then poll for completion." ,
572+ requiredVars : [ "appId" , "appToken" ] ,
568573 steps : [
569574 { tool : "ethora-app-select" , args : { appId : "<APP_ID>" , appToken : "<APP_TOKEN>" } } ,
570575 { tool : "ethora-auth-use-app" } ,
@@ -573,12 +578,13 @@ function runRecipeTool(server: McpServer) {
573578 ] ,
574579 } )
575580 }
576- if ( effectiveGoal === "sources-ingest" ) {
581+ if ( includeAll || effectiveGoal === "sources-ingest" ) {
577582 out . recipes . push (
578583 {
579584 id : "sources-site-crawl-v2" ,
580585 title : "Ingest website (Sources v2 crawl)" ,
581586 description : "Crawl a website for RAG ingestion using app-token auth." ,
587+ requiredVars : [ "appId" , "appToken" ] ,
582588 steps : [
583589 { tool : "ethora-app-select" , args : { appId : "<APP_ID>" , appToken : "<APP_TOKEN>" } } ,
584590 { tool : "ethora-auth-use-app" } ,
@@ -591,6 +597,7 @@ function runRecipeTool(server: McpServer) {
591597 id : "sources-docs-upload-v2" ,
592598 title : "Upload docs for ingestion (Sources v2 docs)" ,
593599 description : "Upload documents for parsing + embeddings using app-token auth." ,
600+ requiredVars : [ "appId" , "appToken" , "base64Content" ] ,
594601 steps : [
595602 { tool : "ethora-app-select" , args : { appId : "<APP_ID>" , appToken : "<APP_TOKEN>" } } ,
596603 { tool : "ethora-auth-use-app" } ,
@@ -599,11 +606,12 @@ function runRecipeTool(server: McpServer) {
599606 }
600607 )
601608 }
602- if ( effectiveGoal === "bot-manage" ) {
609+ if ( includeAll || effectiveGoal === "bot-manage" ) {
603610 out . recipes . push ( {
604611 id : "bot-enable-and-tune" ,
605612 title : "Enable bot + tune settings (v2)" ,
606613 description : "Enable a bot for an app and update its prompt/greeting." ,
614+ requiredVars : [ "appId" , "appToken" ] ,
607615 steps : [
608616 { tool : "ethora-app-select" , args : { appId : "<APP_ID>" , appToken : "<APP_TOKEN>" } } ,
609617 { tool : "ethora-auth-use-app" } ,
@@ -612,12 +620,13 @@ function runRecipeTool(server: McpServer) {
612620 ] ,
613621 } )
614622 }
615- if ( effectiveGoal === "user-login" || effectiveGoal === "files-upload" ) {
623+ if ( includeAll || effectiveGoal === "user-login" || effectiveGoal === "files-upload" ) {
616624 out . recipes . push (
617625 {
618626 id : "user-login" ,
619627 title : "User login (for user-auth tools like files)" ,
620628 description : "Configure appJwt (if needed), switch to user auth, and login." ,
629+ requiredVars : [ "appJwt" , "email" , "password" ] ,
621630 steps : [
622631 { tool : "ethora-configure" , args : { apiUrl, appJwt : "<APP_JWT>" } } ,
623632 { tool : "ethora-auth-use-user" } ,
@@ -628,6 +637,7 @@ function runRecipeTool(server: McpServer) {
628637 id : "files-upload-v2" ,
629638 title : "Upload files (v2)" ,
630639 description : "Login a user, then call the v2 files upload tool." ,
640+ requiredVars : [ "email" , "password" , "base64Content" ] ,
631641 steps : [
632642 { tool : "ethora-auth-use-user" } ,
633643 { tool : "ethora-user-login" , args : { email : "<EMAIL>" , password : "<PASSWORD>" } } ,
@@ -639,9 +649,14 @@ function runRecipeTool(server: McpServer) {
639649 return out
640650 } ) ( )
641651
652+ // List available runnable recipes when recipeId is omitted.
653+ if ( ! recipeId ) {
654+ return asToolResult ( ok ( { goal : effectiveGoal , recipes : helpRes ?. recipes || [ ] } , meta ) )
655+ }
656+
642657 const recipe = ( helpRes ?. recipes || [ ] ) . find ( ( r : any ) => r . id === String ( recipeId ) )
643658 if ( ! recipe ) {
644- return asToolResult ( fail ( new Error ( `Unknown recipeId '${ recipeId } ' for goal '${ effectiveGoal } '. Try ethora-help first .` ) , meta ) )
659+ return asToolResult ( fail ( new Error ( `Unknown recipeId '${ recipeId } ' for goal '${ effectiveGoal } '. Call ethora-run-recipe without recipeId to list available recipes .` ) , meta ) )
645660 }
646661
647662 const v = ( vars && typeof vars === "object" ) ? ( vars as any ) : { }
0 commit comments