Skip to main content
Glama
requirement-schema.ts5.38 kB
import { z } from 'zod'; const tagSchema = z.object({ key: z.string(), value: z.string(), }); const prioritySchema = z.enum(['critical', 'high', 'medium', 'low']); const categorySchema = z.enum(['functional', 'non-functional', 'technical', 'business']); const sourceTypeSchema = z.enum(['user-request', 'discovered', 'derived']); // Source schema with type required when source is provided const requirementSourceSchema = z.object({ type: sourceTypeSchema, // REQUIRED when source object is provided context: z.string().optional(), parentId: z.string().optional(), }); const requirementStatusSchema = z.enum(['draft', 'approved', 'implemented', 'deferred', 'rejected']); const riskLevelSchema = z.enum(['low', 'medium', 'high']); const MAX_COMPLEXITY_ESTIMATE = 10; const impactSchema = z.object({ scope: z.array(z.string()), complexityEstimate: z.number().min(1).max(MAX_COMPLEXITY_ESTIMATE), riskLevel: riskLevelSchema, }); const requirementDataSchema = z.object({ title: z.string().optional(), description: z.string().optional(), rationale: z.string().optional(), source: requirementSourceSchema.optional(), acceptanceCriteria: z.array(z.string()).optional(), priority: prioritySchema.optional(), category: categorySchema.optional(), tags: z.array(tagSchema).optional(), status: requirementStatusSchema.optional(), votes: z.number().optional(), impact: impactSchema.optional(), }); const requirementFiltersSchema = z.object({ status: z.string().optional(), priority: z.string().optional(), category: z.string().optional(), }); // Base schema with all fields const baseRequirementSchema = z.object({ action: z.enum(['add', 'get', 'get_many', 'update', 'list', 'delete', 'vote', 'unvote', 'get_history', 'diff', 'reset_all_votes', 'list_fields']), planId: z.string(), requirementId: z.string().optional(), requirementIds: z.array(z.string()).optional(), requirement: requirementDataSchema.optional(), updates: z.record(z.string(), z.unknown()).optional(), filters: requirementFiltersSchema.optional(), includeTraceability: z.boolean().optional(), force: z.boolean().optional(), fields: z.array(z.string()).optional(), excludeMetadata: z.boolean().optional(), // BUG-018, BUG-019: For list action limit: z.number().optional(), offset: z.number().optional(), // For diff action version1: z.number().optional(), version2: z.number().optional(), }); // Type for the base schema type RequirementInput = z.infer<typeof baseRequirementSchema>; // Schema with superRefine for required field validation based on action export const requirementSchema = baseRequirementSchema.superRefine((data: RequirementInput, ctx) => { switch (data.action) { case 'add': // requirement and requirement.title are required if (data.requirement === undefined) { ctx.addIssue({ code: 'custom', message: 'requirement object is required for add action', path: ['requirement'], }); return; } if (typeof data.requirement.title !== 'string' || data.requirement.title === '') { ctx.addIssue({ code: 'custom', message: 'requirement.title is required for add action', path: ['requirement', 'title'], }); } break; case 'get': case 'delete': case 'vote': case 'unvote': case 'get_history': case 'diff': // requirementId is required if (typeof data.requirementId !== 'string' || data.requirementId === '') { ctx.addIssue({ code: 'custom', message: `requirementId is required for ${data.action} action`, path: ['requirementId'], }); } break; case 'get_many': // requirementIds is required if (!Array.isArray(data.requirementIds) || data.requirementIds.length === 0) { ctx.addIssue({ code: 'custom', message: 'requirementIds is required for get_many action', path: ['requirementIds'], }); } break; case 'update': // requirementId and updates are required if (typeof data.requirementId !== 'string' || data.requirementId === '') { ctx.addIssue({ code: 'custom', message: 'requirementId is required for update action', path: ['requirementId'], }); } if (data.updates === undefined) { ctx.addIssue({ code: 'custom', message: 'updates object is required for update action', path: ['updates'], }); } break; case 'list': case 'reset_all_votes': case 'list_fields': // Only planId is required (already validated by base schema) break; } }); export const requirementToolDescription = 'Manage project requirements - the foundation of planning workflow. Add requirements first, then propose solutions with `solution` tool to address them. Link requirements to phases for implementation tracking. Use `query` tool to trace requirement coverage. Use vote/unvote to prioritize requirements based on user feedback - each requirement has a votes field (default: 0) that can be incremented/decremented. Use reset_all_votes to reset all requirement votes to 0 in a plan. Actions: add, get, get_many, update, list, delete, vote, unvote, get_history, diff, reset_all_votes';

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