Skip to main content
Glama

analyze_requirements

Read-onlyIdempotent

Analyze project requirements to identify essential features, prioritize needs, and define constraints using structured methods like MoSCoW or Kano analysis.

Instructions

요구사항 분석|필요한 것들|requirements analysis|what we need|analyze requirements|필수 기능 - Analyze project requirements

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
requirementsYesList of requirements to analyze
stakeholdersNoProject stakeholders (e.g., users, admins, developers)
constraintsNoProject constraints (timeline, budget, technical)
analysisMethodNoAnalysis methodmoscow

Implementation Reference

  • The main handler function for 'analyze_requirements' tool. Parses input requirements, categorizes them by type, priority (MoSCoW), complexity, risk, estimates effort, identifies stakeholders, computes breakdowns, and returns a comprehensive Markdown-formatted analysis report.
    export async function analyzeRequirements(args: {
      requirements: string;
      stakeholders?: string;
      constraints?: string;
      analysisMethod?: string;
    }): Promise<ToolResult> {
      const {
        requirements,
        stakeholders = 'end users, product owner, development team',
        constraints = 'standard timeline and budget constraints',
        analysisMethod = 'moscow'
      } = args;
    
      // Parse requirements
      const requirementList = requirements.split(/[,\n]/).map(r => r.trim()).filter(r => r.length > 0);
      const stakeholderList = stakeholders.split(',').map(s => s.trim());
    
      const analyzedRequirements: Requirement[] = requirementList.map((req, index) => {
        const reqId = `REQ-${String(index + 1).padStart(3, '0')}`;
        
        // Determine requirement type
        let type: 'functional' | 'non-functional' | 'business' | 'technical' = 'functional';
        if (req.toLowerCase().includes('performance') || req.toLowerCase().includes('security') || req.toLowerCase().includes('scalability')) {
          type = 'non-functional';
        } else if (req.toLowerCase().includes('business') || req.toLowerCase().includes('revenue') || req.toLowerCase().includes('cost')) {
          type = 'business';
        } else if (req.toLowerCase().includes('infrastructure') || req.toLowerCase().includes('architecture') || req.toLowerCase().includes('database')) {
          type = 'technical';
        }
    
        // Determine priority using MoSCoW
        let priority: 'must-have' | 'should-have' | 'could-have' | 'wont-have' = 'should-have';
        if (req.toLowerCase().includes('critical') || req.toLowerCase().includes('essential') || req.toLowerCase().includes('required')) {
          priority = 'must-have';
        } else if (req.toLowerCase().includes('important') || req.toLowerCase().includes('needed')) {
          priority = 'should-have';
        } else if (req.toLowerCase().includes('nice') || req.toLowerCase().includes('optional') || req.toLowerCase().includes('enhancement')) {
          priority = 'could-have';
        } else if (req.toLowerCase().includes('future') || req.toLowerCase().includes('later') || req.toLowerCase().includes('v2')) {
          priority = 'wont-have';
        }
    
        // Assess complexity
        let complexity: 'low' | 'medium' | 'high' = 'medium';
        if (req.length > 100 || req.toLowerCase().includes('complex') || req.toLowerCase().includes('integration') || req.toLowerCase().includes('advanced')) {
          complexity = 'high';
        } else if (req.length < 50 || req.toLowerCase().includes('simple') || req.toLowerCase().includes('basic')) {
          complexity = 'low';
        }
    
        // Assess risk
        let risk: 'low' | 'medium' | 'high' = 'low';
        if (req.toLowerCase().includes('external') || req.toLowerCase().includes('third-party') || req.toLowerCase().includes('new technology')) {
          risk = 'high';
        } else if (req.toLowerCase().includes('integration') || req.toLowerCase().includes('performance') || complexity === 'high') {
          risk = 'medium';
        }
    
        // Estimate effort
        let estimatedEffort = '3-5 days';
        if (complexity === 'high') {
          estimatedEffort = '1-3 weeks';
        } else if (complexity === 'low') {
          estimatedEffort = '1-2 days';
        }
    
        // Determine relevant stakeholders
        const relevantStakeholders = stakeholderList.filter(stakeholder => {
          if (type === 'business' && stakeholder.toLowerCase().includes('owner')) return true;
          if (type === 'technical' && stakeholder.toLowerCase().includes('developer')) return true;
          if (type === 'functional' && stakeholder.toLowerCase().includes('user')) return true;
          return true; // Include all by default
        });
    
        return {
          id: reqId,
          title: req.length > 50 ? req.substring(0, 47) + '...' : req,
          description: req,
          type,
          priority,
          complexity,
          risk,
          dependencies: [],
          estimatedEffort,
          stakeholders: relevantStakeholders
        };
      });
    
      const analysis = {
        action: 'analyze_requirements',
        method: analysisMethod,
        totalRequirements: analyzedRequirements.length,
        requirements: analyzedRequirements,
        priorityBreakdown: {
          mustHave: analyzedRequirements.filter(r => r.priority === 'must-have').length,
          shouldHave: analyzedRequirements.filter(r => r.priority === 'should-have').length,
          couldHave: analyzedRequirements.filter(r => r.priority === 'could-have').length,
          wontHave: analyzedRequirements.filter(r => r.priority === 'wont-have').length
        },
        typeBreakdown: {
          functional: analyzedRequirements.filter(r => r.type === 'functional').length,
          nonFunctional: analyzedRequirements.filter(r => r.type === 'non-functional').length,
          business: analyzedRequirements.filter(r => r.type === 'business').length,
          technical: analyzedRequirements.filter(r => r.type === 'technical').length
        },
        riskAssessment: {
          high: analyzedRequirements.filter(r => r.risk === 'high').length,
          medium: analyzedRequirements.filter(r => r.risk === 'medium').length,
          low: analyzedRequirements.filter(r => r.risk === 'low').length
        },
        recommendations: [
          'Focus on Must-Have requirements for MVP',
          'Validate high-risk requirements early',
          'Consider Should-Have items for post-MVP releases',
          'Review Could-Have items based on resource availability',
          'Plan technical requirements to support functional ones'
        ],
        constraints: constraints,
        status: 'success'
      };
    
      // Format output
      let formattedOutput = `# Requirements Analysis\n\n`;
      formattedOutput += `**Analysis Method:** ${analysisMethod.toUpperCase()}  \n`;
      formattedOutput += `**Total Requirements:** ${analysis.totalRequirements}  \n`;
      formattedOutput += `**Constraints:** ${constraints}\n\n`;
    
      formattedOutput += `## Priority Breakdown (MoSCoW)\n`;
      formattedOutput += `- **Must Have:** ${analysis.priorityBreakdown.mustHave}\n`;
      formattedOutput += `- **Should Have:** ${analysis.priorityBreakdown.shouldHave}\n`;
      formattedOutput += `- **Could Have:** ${analysis.priorityBreakdown.couldHave}\n`;
      formattedOutput += `- **Won't Have:** ${analysis.priorityBreakdown.wontHave}\n\n`;
    
      formattedOutput += `## Risk Assessment\n`;
      formattedOutput += `- **High Risk:** ${analysis.riskAssessment.high} requirements\n`;
      formattedOutput += `- **Medium Risk:** ${analysis.riskAssessment.medium} requirements\n`;
      formattedOutput += `- **Low Risk:** ${analysis.riskAssessment.low} requirements\n\n`;
    
      formattedOutput += `## Detailed Requirements\n\n`;
    
      // Group by priority
      const priorities = ['must-have', 'should-have', 'could-have', 'wont-have'] as const;
      priorities.forEach(priority => {
        const reqsForPriority = analyzedRequirements.filter(r => r.priority === priority);
        if (reqsForPriority.length > 0) {
          formattedOutput += `### ${priority.toUpperCase().replace('-', ' ')} (${reqsForPriority.length})\n\n`;
          reqsForPriority.forEach(req => {
            formattedOutput += `**${req.id}:** ${req.title}  \n`;
            formattedOutput += `*Type:* ${req.type} | *Complexity:* ${req.complexity} | *Risk:* ${req.risk} | *Effort:* ${req.estimatedEffort}  \n`;
            formattedOutput += `*Stakeholders:* ${req.stakeholders.join(', ')}\n\n`;
          });
        }
      });
    
      formattedOutput += `## Recommendations\n`;
      analysis.recommendations.forEach(rec => {
        formattedOutput += `- ${rec}\n`;
      });
    
      return {
        content: [{ type: 'text', text: formattedOutput }]
      };
    }
  • ToolDefinition schema for 'analyze_requirements', defining input schema with requirements (required), optional stakeholders, constraints, analysisMethod (enum: moscow, kano, value-effort), and annotations.
    export const analyzeRequirementsDefinition: ToolDefinition = {
      name: 'analyze_requirements',
      description: '요구사항 분석|필요한 것들|requirements analysis|what we need|analyze requirements|필수 기능 - Analyze project requirements',
      inputSchema: {
        type: 'object',
        properties: {
          requirements: { type: 'string', description: 'List of requirements to analyze' },
          stakeholders: { type: 'string', description: 'Project stakeholders (e.g., users, admins, developers)' },
          constraints: { type: 'string', description: 'Project constraints (timeline, budget, technical)' },
          analysisMethod: { type: 'string', description: 'Analysis method', enum: ['moscow', 'kano', 'value-effort'], default: 'moscow' }
        },
        required: ['requirements']
      },
      annotations: {
        title: 'Analyze Requirements',
        audience: ['user', 'assistant'],
        readOnlyHint: true,
        destructiveHint: false,
        idempotentHint: true,
        openWorldHint: false
      }
    };
  • src/index.ts:199-199 (registration)
    Registration of the analyzeRequirements handler function in the toolHandlers map under key 'analyze_requirements' for dynamic tool dispatch.
    'analyze_requirements': analyzeRequirements,
  • src/index.ts:132-132 (registration)
    Inclusion of analyzeRequirementsDefinition in the tools array returned by ListToolsRequestHandler.
    analyzeRequirementsDefinition,
  • src/index.ts:69-69 (registration)
    Import statement bringing in the tool definition and handler from the implementation file.
    import { analyzeRequirementsDefinition, analyzeRequirements } from './tools/planning/analyzeRequirements.js';
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate readOnlyHint=true, destructiveHint=false, idempotentHint=true, and openWorldHint=false, which already convey that this is a safe, non-destructive, and deterministic operation. The description adds no behavioral context beyond this, such as rate limits or authentication needs. However, it does not contradict the annotations, so it meets the lower bar set by the annotations without adding significant value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a repetitive list of phrases ('요구사항 분석|필요한 것들|requirements analysis|what we need|analyze requirements|필수 기능 - Analyze project requirements') that lack structure and front-loading. It wastes space by restating the same concept in multiple languages without adding clarity or value, making it inefficient and poorly organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (4 parameters, 100% schema coverage, annotations provided, no output schema), the description is incomplete. It fails to explain what the analysis outputs or how it integrates with sibling tools, leaving gaps in understanding the tool's role. However, annotations cover safety and determinism, partially compensating for the description's shortcomings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with clear descriptions for all parameters (e.g., 'requirements' as a list to analyze, 'analysisMethod' with enum options). The description adds no parameter semantics beyond what the schema provides, such as explaining how parameters interact or their impact on analysis. Baseline 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description '요구사항 분석|필요한 것들|requirements analysis|what we need|analyze requirements|필수 기능 - Analyze project requirements' is vague and repetitive. It lists multiple phrases that essentially restate the tool name ('analyze requirements') without specifying what the analysis produces or how it differs from sibling tools like 'analyze_complexity' or 'analyze_problem'. The purpose is implied but lacks specificity about the verb+resource outcome.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It does not mention any context, prerequisites, or exclusions, nor does it differentiate from sibling tools such as 'analyze_complexity' or 'generate_prd'. Without such information, the agent must infer usage from the tool name alone, which is insufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/su-record/hi-ai'

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