Skip to main content
Glama
solution-schema.ts4.82 kB
import { z } from 'zod'; const tagSchema = z.object({ key: z.string(), value: z.string(), }); const effortUnitSchema = z.enum(['minutes', 'hours', 'days', 'weeks', 'story-points']); const confidenceSchema = z.enum(['low', 'medium', 'high']); const feasibilitySchema = z.enum(['high', 'medium', 'low']); const solutionStatusSchema = z.enum(['proposed', 'evaluated', 'selected', 'rejected', 'implemented']); const MAX_TRADEOFF_SCORE = 10; const effortEstimateSchema = z.object({ value: z.number(), unit: effortUnitSchema, confidence: confidenceSchema, }); const tradeoffSchema = z.object({ aspect: z.string(), pros: z.array(z.string()), cons: z.array(z.string()), score: z.number().min(1).max(MAX_TRADEOFF_SCORE).optional(), }); const evaluationSchema = z.object({ effortEstimate: effortEstimateSchema.optional(), technicalFeasibility: feasibilitySchema.optional(), riskAssessment: z.string().optional(), dependencies: z.array(z.string()).optional(), performanceImpact: z.string().optional(), }); const solutionDataSchema = z.object({ title: z.string().optional(), description: z.string().optional(), approach: z.string().optional(), implementationNotes: z.string().optional(), tradeoffs: z.array(tradeoffSchema).optional(), addressing: z.array(z.string()).optional(), evaluation: evaluationSchema.optional(), status: solutionStatusSchema.optional(), selectionReason: z.string().optional(), tags: z.array(tagSchema).optional(), }); // Base schema with all fields const baseSolutionSchema = z.object({ action: z.enum(['propose', 'get', 'get_many', 'update', 'list', 'compare', 'select', 'delete', 'get_history', 'diff', 'list_fields']), planId: z.string(), solutionId: z.string().optional(), solutionIds: z.array(z.string()).optional(), solution: solutionDataSchema.optional(), updates: z.record(z.string(), z.unknown()).optional(), aspects: z.array(z.string()).optional(), reason: z.string().optional(), createDecisionRecord: z.boolean().optional(), fields: z.array(z.string()).optional(), excludeMetadata: z.boolean().optional(), // For diff action version1: z.number().optional(), version2: z.number().optional(), }); // Type for the base schema type SolutionInput = z.infer<typeof baseSolutionSchema>; // Schema with superRefine for required field validation based on action export const solutionSchema = baseSolutionSchema.superRefine((data: SolutionInput, ctx) => { switch (data.action) { case 'propose': // solution and solution.title are required if (data.solution === undefined) { ctx.addIssue({ code: 'custom', message: 'solution object is required for propose action', path: ['solution'], }); return; } if (typeof data.solution.title !== 'string' || data.solution.title === '') { ctx.addIssue({ code: 'custom', message: 'solution.title is required for propose action', path: ['solution', 'title'], }); } break; case 'get': case 'delete': case 'select': case 'get_history': case 'diff': // solutionId is required if (typeof data.solutionId !== 'string' || data.solutionId === '') { ctx.addIssue({ code: 'custom', message: `solutionId is required for ${data.action} action`, path: ['solutionId'], }); } break; case 'get_many': case 'compare': // solutionIds is required if (!Array.isArray(data.solutionIds) || data.solutionIds.length === 0) { ctx.addIssue({ code: 'custom', message: `solutionIds is required for ${data.action} action`, path: ['solutionIds'], }); } break; case 'update': // solutionId and updates are required if (typeof data.solutionId !== 'string' || data.solutionId === '') { ctx.addIssue({ code: 'custom', message: 'solutionId is required for update action', path: ['solutionId'], }); } if (data.updates === undefined) { ctx.addIssue({ code: 'custom', message: 'updates object is required for update action', path: ['updates'], }); } break; case 'list': case 'list_fields': // Only planId is required (already validated by base schema) break; } }); export const solutionToolDescription = 'Manage solution proposals for requirements. Propose multiple solutions with tradeoff analysis, compare them to evaluate options, then select the best one. Use `decision` tool to record selection rationale. Selected solutions guide phase implementation. Actions: propose, get, get_many, update, list, compare, select, delete, get_history, diff.';

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cppmyjob/cpp-mcp-planner'

If you have feedback or need assistance with the MCP directory API, please join our Discord server