11import { db } from '@sim/db'
2- import { workflowMcpServer , workflowMcpTool } from '@sim/db/schema'
2+ import { workflow , workflowMcpServer , workflowMcpTool } from '@sim/db/schema'
33import { createLogger } from '@sim/logger'
44import { eq , inArray , sql } from 'drizzle-orm'
55import type { NextRequest } from 'next/server'
66import { getParsedBody , withMcpAuth } from '@/lib/mcp/middleware'
77import { createMcpErrorResponse , createMcpSuccessResponse } from '@/lib/mcp/utils'
8+ import { sanitizeToolName } from '@/lib/mcp/workflow-tool-schema'
9+ import { hasValidStartBlock } from '@/lib/workflows/triggers/trigger-utils.server'
810
911const logger = createLogger ( 'WorkflowMcpServersAPI' )
1012
@@ -25,18 +27,18 @@ export const GET = withMcpAuth('read')(
2527 createdBy : workflowMcpServer . createdBy ,
2628 name : workflowMcpServer . name ,
2729 description : workflowMcpServer . description ,
30+ isPublic : workflowMcpServer . isPublic ,
2831 createdAt : workflowMcpServer . createdAt ,
2932 updatedAt : workflowMcpServer . updatedAt ,
3033 toolCount : sql < number > `(
31- SELECT COUNT(*)::int
32- FROM "workflow_mcp_tool"
34+ SELECT COUNT(*)::int
35+ FROM "workflow_mcp_tool"
3336 WHERE "workflow_mcp_tool"."server_id" = "workflow_mcp_server"."id"
3437 )` . as ( 'tool_count' ) ,
3538 } )
3639 . from ( workflowMcpServer )
3740 . where ( eq ( workflowMcpServer . workspaceId , workspaceId ) )
3841
39- // Fetch all tools for these servers
4042 const serverIds = servers . map ( ( s ) => s . id )
4143 const tools =
4244 serverIds . length > 0
@@ -49,7 +51,6 @@ export const GET = withMcpAuth('read')(
4951 . where ( inArray ( workflowMcpTool . serverId , serverIds ) )
5052 : [ ]
5153
52- // Group tool names by server
5354 const toolNamesByServer : Record < string , string [ ] > = { }
5455 for ( const tool of tools ) {
5556 if ( ! toolNamesByServer [ tool . serverId ] ) {
@@ -58,7 +59,6 @@ export const GET = withMcpAuth('read')(
5859 toolNamesByServer [ tool . serverId ] . push ( tool . toolName )
5960 }
6061
61- // Attach tool names to servers
6262 const serversWithToolNames = servers . map ( ( server ) => ( {
6363 ...server ,
6464 toolNames : toolNamesByServer [ server . id ] || [ ] ,
@@ -90,6 +90,7 @@ export const POST = withMcpAuth('write')(
9090 logger . info ( `[${ requestId } ] Creating workflow MCP server:` , {
9191 name : body . name ,
9292 workspaceId,
93+ workflowIds : body . workflowIds ,
9394 } )
9495
9596 if ( ! body . name ) {
@@ -110,16 +111,76 @@ export const POST = withMcpAuth('write')(
110111 createdBy : userId ,
111112 name : body . name . trim ( ) ,
112113 description : body . description ?. trim ( ) || null ,
114+ isPublic : body . isPublic ?? false ,
113115 createdAt : new Date ( ) ,
114116 updatedAt : new Date ( ) ,
115117 } )
116118 . returning ( )
117119
120+ const workflowIds : string [ ] = body . workflowIds || [ ]
121+ const addedTools : Array < { workflowId : string ; toolName : string } > = [ ]
122+
123+ if ( workflowIds . length > 0 ) {
124+ const workflows = await db
125+ . select ( {
126+ id : workflow . id ,
127+ name : workflow . name ,
128+ description : workflow . description ,
129+ isDeployed : workflow . isDeployed ,
130+ workspaceId : workflow . workspaceId ,
131+ } )
132+ . from ( workflow )
133+ . where ( inArray ( workflow . id , workflowIds ) )
134+
135+ for ( const workflowRecord of workflows ) {
136+ if ( workflowRecord . workspaceId !== workspaceId ) {
137+ logger . warn (
138+ `[${ requestId } ] Skipping workflow ${ workflowRecord . id } - does not belong to workspace`
139+ )
140+ continue
141+ }
142+
143+ if ( ! workflowRecord . isDeployed ) {
144+ logger . warn ( `[${ requestId } ] Skipping workflow ${ workflowRecord . id } - not deployed` )
145+ continue
146+ }
147+
148+ const hasStartBlock = await hasValidStartBlock ( workflowRecord . id )
149+ if ( ! hasStartBlock ) {
150+ logger . warn ( `[${ requestId } ] Skipping workflow ${ workflowRecord . id } - no start block` )
151+ continue
152+ }
153+
154+ const toolName = sanitizeToolName ( workflowRecord . name )
155+ const toolDescription =
156+ workflowRecord . description || `Execute ${ workflowRecord . name } workflow`
157+
158+ const toolId = crypto . randomUUID ( )
159+ await db . insert ( workflowMcpTool ) . values ( {
160+ id : toolId ,
161+ serverId,
162+ workflowId : workflowRecord . id ,
163+ toolName,
164+ toolDescription,
165+ parameterSchema : { } ,
166+ createdAt : new Date ( ) ,
167+ updatedAt : new Date ( ) ,
168+ } )
169+
170+ addedTools . push ( { workflowId : workflowRecord . id , toolName } )
171+ }
172+
173+ logger . info (
174+ `[${ requestId } ] Added ${ addedTools . length } tools to server ${ serverId } :` ,
175+ addedTools . map ( ( t ) => t . toolName )
176+ )
177+ }
178+
118179 logger . info (
119180 `[${ requestId } ] Successfully created workflow MCP server: ${ body . name } (ID: ${ serverId } )`
120181 )
121182
122- return createMcpSuccessResponse ( { server } , 201 )
183+ return createMcpSuccessResponse ( { server, addedTools } , 201 )
123184 } catch ( error ) {
124185 logger . error ( `[${ requestId } ] Error creating workflow MCP server:` , error )
125186 return createMcpErrorResponse (
0 commit comments