UNPKG

@grebyn/toolflow-mcp-server

Version:

MCP server for managing other MCP servers - discover, install, organize into bundles, and automate with workflows. Uses StreamableHTTP transport with dual OAuth/API key authentication.

187 lines (184 loc) 8.63 kB
import { ApiClient } from '../../utils/api-client.js'; export const createWorkflowTool = { name: 'create_workflow', description: `Save a workflow with instructions and required MCP servers. Best used after completing a multi-step task that could be reused. The AI should analyze what was done and create clear, reusable instructions. Only create workflows for substantial, complete tasks (e.g., 'Deploy Next.js to Vercel', 'Run security audit', 'Update dependencies'). Avoid creating workflows for simple one-off tasks. Key points: - Workflows save both the MCP servers needed AND step-by-step instructions - Instructions should be clear and actionable for AI models - Include expected outcomes and error handling in steps - Tag workflows appropriately for discovery - All workflows are created as private to your organization for security`, inputSchema: { type: 'object', properties: { name: { type: 'string', minLength: 2, maxLength: 100, description: "Clear, action-oriented name (e.g., 'Deploy Next.js to Vercel', 'Run Full Test Suite', 'Generate API Documentation')" }, description: { type: 'string', minLength: 5, maxLength: 500, description: '2-3 sentence description of what this workflow accomplishes and when to use it' }, required_servers: { type: 'object', description: 'MCP server configurations needed, in the same format as bundles. Each key is the server name, value is the config with command, args, env, and optional type', additionalProperties: { type: 'object', properties: { command: { type: 'string' }, args: { type: 'array', items: { type: 'string' } }, env: { type: 'object', additionalProperties: { type: 'string' } }, type: { type: 'string', enum: ['stdio', 'http', 'sse'] } }, required: ['command', 'args'] } }, instructions: { type: 'object', description: 'Step-by-step instructions in structured format for AI execution', properties: { steps: { type: 'array', items: { type: 'object', properties: { action: { type: 'string', description: 'What action to perform (e.g., check_git_status, run_tests, deploy)' }, tool: { type: 'string', description: 'Which MCP server/tool to use for this step' }, description: { type: 'string', description: 'Clear description of what this step does' }, command: { type: 'string', description: 'Optional specific command to run (e.g., npm test)' }, expected_outcome: { type: 'string', description: 'What success looks like for this step' }, on_failure: { type: 'string', enum: ['stop_and_report', 'continue', 'skip'], description: 'What to do if this step fails' }, capture_output: { type: 'array', items: { type: 'string' }, description: 'Output variables to capture for use in later steps' }, use_captured: { type: 'array', items: { type: 'string' }, description: 'Previously captured variables to use in this step' } }, required: ['action', 'description'] } } }, required: ['steps'] }, user_provided_instructions: { type: 'string', description: 'Optional: If user provided specific instructions, include them here for reference' }, tags: { type: 'array', items: { type: 'string' }, default: [], description: "Tags for categorization (e.g., ['deployment', 'vercel', 'nextjs'], ['testing', 'jest'], ['documentation'])" }, install_commands: { type: 'array', items: { type: 'string' }, default: [], description: 'Optional array of shell commands to run before installing the required MCP servers. Examples: ["npm install -g @modelcontextprotocol/server-filesystem", "pip install mcp-server-git"]' }, }, required: ['name', 'description', 'required_servers', 'instructions'], // additionalProperties: false }, async execute(args, context) { try { // Validate user has authentication if (!context.token) { return { content: [{ type: 'text', text: 'User authentication required' }] }; } // Validate instructions have at least one step if (!args.instructions.steps || args.instructions.steps.length === 0) { return { content: [{ type: 'text', text: 'Workflow must have at least one instruction step' }] }; } // Create the workflow using API const workflow = await ApiClient.createWorkflow({ name: args.name, description: args.description, required_servers: args.required_servers, instructions: args.instructions, tags: args.tags || [], install_commands: args.install_commands || [] }, context); if (!workflow) { return { content: [{ type: 'text', text: 'Failed to create workflow' }] }; } // Build success message const serverCount = Object.keys(args.required_servers).length; const stepCount = args.instructions.steps.length; return { content: [{ type: 'text', text: `✅ Successfully created workflow "${workflow.name}" (ID: ${workflow.id}) Description: ${workflow.description} Required servers: ${serverCount} MCP servers Instructions: ${stepCount} steps Tags: ${args.tags?.join(', ') || 'none'} Install commands: ${args.install_commands?.length || 0} command(s) The workflow has been saved and can now be discovered and executed using list_workflows and perform_workflow.` }] }; } catch (error) { console.error('Error creating workflow:', error); return { content: [{ type: 'text', text: `An unexpected error occurred: ${error instanceof Error ? error.message : 'Unknown error'}` }] }; } } }; //# sourceMappingURL=createWorkflow.js.map