Skip to main content
Glama

precommit

Validate code changes before committing to detect security risks, performance issues, breaking changes, and quality problems using AI analysis.

Instructions

Pre-commit validation for code changes

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
taskYesWhat to validate for pre-commit (e.g., 'review changes before commit', 'validate security implications', 'check for breaking changes')
filesNoSpecific files to validate (optional - will analyze git changes if not provided)
focusNoValidation focus areaall
includeStagedNoInclude staged changes in validation
includeUnstagedNoInclude unstaged changes in validation
compareToNoGit ref to compare against (e.g., 'main', 'HEAD~1'). If not provided, analyzes current changes
severityNoMinimum severity level to reportmedium
providerNoAI provider to usegemini

Implementation Reference

  • The main execution logic for the precommit tool. Uses AI providers to analyze code changes, validate against specified focus areas (security, performance, etc.), and returns a structured report with approval status and recommendations.
    async handlePrecommit(params: z.infer<typeof PrecommitSchema>) { const providerName = params.provider || (await this.providerManager.getPreferredProvider(['openai', 'gemini', 'azure', 'grok'])); const provider = await this.providerManager.getProvider(providerName); // Build focus-specific system prompt const focusPrompts = { security: "Focus on security implications, potential vulnerabilities, authentication issues, data exposure risks, and security best practices.", performance: "Focus on performance impact, efficiency concerns, resource usage, scalability implications, and optimization opportunities.", quality: "Focus on code quality, maintainability, readability, design patterns, architecture concerns, and technical debt.", tests: "Focus on test coverage, test quality, edge cases, testing strategies, and verification completeness.", "breaking-changes": "Focus on breaking changes, API compatibility, backward compatibility, and impact on existing functionality.", all: "Provide comprehensive validation covering security, performance, quality, tests, and breaking changes.", }; const systemPrompt = `You are an expert code reviewer specializing in pre-commit validation and change analysis. Your role is to thoroughly examine code changes and provide comprehensive feedback before commits. VALIDATION FOCUS: ${focusPrompts[params.focus]} ANALYSIS AREAS: 1. **Change Impact**: Understand what's being modified and why 2. **Risk Assessment**: Identify potential issues and their severity 3. **Quality Validation**: Check code quality, patterns, and maintainability 4. **Security Review**: Look for security implications and vulnerabilities 5. **Performance Considerations**: Evaluate performance impact 6. **Test Coverage**: Assess testing adequacy for changes 7. **Breaking Changes**: Identify potential compatibility issues RESPONSE FORMAT: Provide a structured pre-commit validation report that includes: - **Summary**: Brief overview of changes and overall assessment - **Critical Issues**: High-severity problems that must be addressed - **Concerns**: Medium-severity issues worth reviewing - **Recommendations**: Suggestions for improvement - **Approval Status**: Ready to commit, needs fixes, or requires further review Severity levels: Critical (blocks commit), High (should fix), Medium (consider fixing), Low (minor improvements)`; // Build the validation prompt let prompt = `Pre-commit Validation Task: ${params.task}`; // Add file context if provided if (params.files && params.files.length > 0) { prompt += `\n\nFiles to validate: ${params.files.join(", ")}`; } else { prompt += `\n\nPlease analyze git changes (staged: ${params.includeStaged}, unstaged: ${params.includeUnstaged})`; if (params.compareTo) { prompt += ` compared to: ${params.compareTo}`; } } prompt += `\n\nValidation focus: ${params.focus} Minimum severity to report: ${params.severity} Please provide a comprehensive pre-commit validation analysis with specific findings and recommendations.`; try { const response = await provider.generateText({ prompt, systemPrompt, temperature: 0.3, // Lower temperature for consistent validation reasoningEffort: (providerName === "openai" || providerName === "azure" || providerName === "grok") ? "high" : undefined, useSearchGrounding: false, // Pre-commit validation doesn't need web search toolName: 'precommit', }); // Build structured response const validation = { task: params.task, focus: params.focus, severity: params.severity, files_analyzed: params.files || "git changes", validation_config: { include_staged: params.includeStaged, include_unstaged: params.includeUnstaged, compare_to: params.compareTo, }, validation_report: response.text, provider_used: providerName, model_used: response.model, }; // Parse validation report to extract key sections (simplified extraction) const reportText = response.text.toLowerCase(); const hasCriticalIssues = reportText.includes("critical") || reportText.includes("blocks commit") || reportText.includes("must fix"); const hasHighIssues = reportText.includes("high") || reportText.includes("should fix"); const hasMediumIssues = reportText.includes("medium") || reportText.includes("consider fixing"); let approvalStatus = "approved"; if (hasCriticalIssues) { approvalStatus = "blocked"; } else if (hasHighIssues) { approvalStatus = "needs_review"; } else if (hasMediumIssues) { approvalStatus = "approved_with_suggestions"; } const result = { validation, approval_status: approvalStatus, has_critical_issues: hasCriticalIssues, has_high_issues: hasHighIssues, has_medium_issues: hasMediumIssues, commit_recommendation: approvalStatus === "approved" ? "Changes look good and are ready to commit." : approvalStatus === "blocked" ? "Critical issues found. Do not commit until resolved." : approvalStatus === "needs_review" ? "High-priority issues found. Consider fixing before commit." : "Changes are acceptable but have suggestions for improvement.", }; return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ], metadata: { toolName: "precommit", focus: params.focus, approvalStatus: approvalStatus, provider: providerName, model: response.model, severity: params.severity, usage: response.usage, ...response.metadata, }, }; } catch (error) { return { content: [ { type: "text", text: JSON.stringify({ error: "Pre-commit validation failed", message: error instanceof Error ? error.message : "Unknown error", task: params.task, focus: params.focus, }, null, 2), }, ], isError: true, }; } }
  • src/server.ts:364-372 (registration)
    Tool registration in the MCP server, linking to the handler in aiHandlers.handlePrecommit and using PrecommitSchema for input validation.
    // Register precommit tool server.registerTool("precommit", { title: "Pre-commit Validation", description: "Pre-commit validation for code changes", inputSchema: PrecommitSchema.shape, }, async (args) => { const aiHandlers = await getHandlers(); return await aiHandlers.handlePrecommit(args); });
  • Input schema definition using Zod for the precommit tool, defining parameters like task, files, focus, git options, and provider.
    const PrecommitSchema = z.object({ task: z.string().describe("What to validate for pre-commit (e.g., 'review changes before commit', 'validate security implications', 'check for breaking changes')"), files: z.array(z.string()).optional().describe("Specific files to validate (optional - will analyze git changes if not provided)"), focus: z.enum(["security", "performance", "quality", "tests", "breaking-changes", "all"]).default("all").describe("Validation focus area"), includeStaged: z.boolean().optional().default(true).describe("Include staged changes in validation"), includeUnstaged: z.boolean().optional().default(false).describe("Include unstaged changes in validation"), compareTo: z.string().optional().describe("Git ref to compare against (e.g., 'main', 'HEAD~1'). If not provided, analyzes current changes"), severity: z.enum(["critical", "high", "medium", "low", "all"]).default("medium").describe("Minimum severity level to report"), provider: z.enum(["openai", "gemini", "azure", "grok"]).optional().default("gemini").describe("AI provider to use"), });
  • Duplicate schema definition in handler file for TypeScript inference (z.infer<typeof PrecommitSchema>) in the handlePrecommit method.
    const PrecommitSchema = z.object({ task: z.string().describe("What to validate for pre-commit (e.g., 'review changes before commit', 'validate security implications', 'check for breaking changes')"), files: z.array(z.string()).optional().describe("Specific files to validate (optional - will analyze git changes if not provided)"), focus: z.enum(["security", "performance", "quality", "tests", "breaking-changes", "all"]).default("all").describe("Validation focus area"), includeStaged: z.boolean().optional().default(true).describe("Include staged changes in validation"), includeUnstaged: z.boolean().optional().default(false).describe("Include unstaged changes in validation"), compareTo: z.string().optional().describe("Git ref to compare against (e.g., 'main', 'HEAD~1'). If not provided, analyzes current changes"), severity: z.enum(["critical", "high", "medium", "low", "all"]).default("medium").describe("Minimum severity level to report"), provider: z.enum(["openai", "gemini", "azure", "grok"]).optional().default("gemini").describe("AI provider to use"), });

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/RealMikeChong/ultra-mcp'

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