flowzap_create_playground
Create a shareable URL to visualize FlowZap code as workflow, sequence, or architecture diagrams in an interactive playground.
Instructions
Create a FlowZap playground session with the given code and return a shareable URL. Use this after generating FlowZap Code to give the user a visual diagram. Set view to 'architecture' when user requests an architecture diagram.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | FlowZap Code to load in the playground | |
| view | No | View mode for the diagram. Use 'architecture' for architecture diagrams, 'sequence' for sequence diagrams, 'workflow' (default) for workflow diagrams. |
Implementation Reference
- src/index.ts:416-440 (handler)The handleCreatePlayground function is the main handler that processes the flowzap_create_playground tool. It first validates the code, then creates a playground session via API, and returns a formatted response with the shareable URL.async function handleCreatePlayground(code: unknown, view?: string): Promise<string> { try { // First validate const validation = await validateCode(code); if (!validation.valid) { const errors = validation.errors?.map((e: any) => `- Line ${e.line}: ${e.message}`).join("\n") || "Unknown error"; return `❌ Cannot create playground - code has errors:\n${errors}`; } // Create playground with optional view parameter const result = await createPlayground(code, view); if (result.url) { const viewLabel = view === "architecture" ? "Architecture Diagram" : view === "sequence" ? "Sequence Diagram" : "Diagram"; return `Your diagram was created successfully.\nView your ${viewLabel}: ${result.url}`; } else if (result.error) { return `❌ Failed to create playground: ${result.error}`; } else { return `❌ Unexpected response from FlowZap API`; } } catch (error) { securityLog("HANDLER_ERROR", { handler: "createPlayground", error: String(error) }); // Don't expose internal error details to client return `❌ Error creating playground. Please try again.`; } }
- src/index.ts:356-394 (helper)The createPlayground helper function performs the actual API call to create a playground session. It includes security features like input sanitization, URL validation, rate limiting, and timeout handling.async function createPlayground(rawCode: unknown, view?: string): Promise<any> { // Input validation const sanitized = sanitizeCode(rawCode); if (!sanitized.valid) { securityLog("INPUT_VALIDATION_FAILED", { error: sanitized.error }); return { error: sanitized.error }; } const code = sanitized.code!; const validViews = ["workflow", "sequence", "architecture"]; const safeView = view && validViews.includes(view) ? view : undefined; securityLog("API_CALL", { endpoint: "playground/create", codeLength: code.length, view: safeView }); const response = await secureFetch(`${FLOWZAP_API_BASE}/api/playground/create`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ code, view: safeView }), }); // Validate response if (!response.ok) { securityLog("API_ERROR", { status: response.status }); throw new Error(`API error: ${response.status}`); } const result = await response.json(); // Sanitize response - only return expected fields, validate URL if (result.url) { // Validate returned URL is from FlowZap if (!isAllowedUrl(result.url) && !result.url.startsWith("https://flowzap.xyz/")) { securityLog("SUSPICIOUS_URL", { url: result.url }); return { error: "Invalid playground URL returned" }; } return { url: result.url }; } return { error: result.error || "Unknown error" }; }
- src/index.ts:169-188 (registration)The flowzap_create_playground tool registration in the tools array, defining its name, description, and input schema with 'code' (required) and 'view' (optional) parameters.{ name: "flowzap_create_playground", description: "Create a FlowZap playground session with the given code and return a shareable URL. Use this after generating FlowZap Code to give the user a visual diagram. Set view to 'architecture' when user requests an architecture diagram.", inputSchema: { type: "object" as const, properties: { code: { type: "string", description: "FlowZap Code to load in the playground", }, view: { type: "string", enum: ["workflow", "sequence", "architecture"], description: "View mode for the diagram. Use 'architecture' for architecture diagrams, 'sequence' for sequence diagrams, 'workflow' (default) for workflow diagrams.", }, }, required: ["code"], }, },
- src/index.ts:480-484 (registration)The switch case that routes flowzap_create_playground tool calls to the handleCreatePlayground handler, extracting the code and view arguments from the request.case "flowzap_create_playground": { const { code, view } = args as { code?: unknown; view?: string }; const result = await handleCreatePlayground(code, view); return { content: [{ type: "text", text: result }] }; }
- src/index.ts:85-107 (helper)The sanitizeCode helper function validates and sanitizes FlowZap Code input, checking type, length, emptiness, and removing dangerous characters like null bytes and control characters.function sanitizeCode(input: unknown): { valid: boolean; code?: string; error?: string } { // Type check if (typeof input !== "string") { return { valid: false, error: "Code must be a string" }; } // Length check if (input.length > MAX_CODE_LENGTH) { return { valid: false, error: `Code exceeds maximum length of ${MAX_CODE_LENGTH} characters` }; } // Empty check if (input.trim().length === 0) { return { valid: false, error: "Code cannot be empty" }; } // Remove null bytes and other dangerous characters const sanitized = input .replace(/\0/g, "") // Null bytes .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, ""); // Control characters except \t, \n, \r return { valid: true, code: sanitized }; }