mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-06 05:23:08 +00:00
feat: add comprehensive performance benchmark tracking system
- Create benchmark test suites for critical operations: - Node loading performance - Database query performance - Search operations performance - Validation performance - MCP tool execution performance - Add GitHub Actions workflow for benchmark tracking: - Runs on push to main and PRs - Uses github-action-benchmark for historical tracking - Comments on PRs with performance results - Alerts on >10% performance regressions - Stores results in GitHub Pages - Create benchmark infrastructure: - Custom Vitest benchmark configuration - JSON reporter for CI results - Result formatter for github-action-benchmark - Performance threshold documentation - Add supporting utilities: - SQLiteStorageService for benchmark database setup - MCPEngine wrapper for testing MCP tools - Test factories for generating benchmark data - Enhanced NodeRepository with benchmark methods - Document benchmark system: - Comprehensive benchmark guide in docs/BENCHMARKS.md - Performance thresholds in .github/BENCHMARK_THRESHOLDS.md - README for benchmarks directory - Integration with existing test suite The benchmark system will help monitor performance over time and catch regressions before they reach production. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
113
src/mcp-tools-engine.ts
Normal file
113
src/mcp-tools-engine.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* MCPEngine - A simplified interface for benchmarking MCP tool execution
|
||||
* This directly implements the MCP tool functionality without server dependencies
|
||||
*/
|
||||
import { NodeRepository } from './database/node-repository';
|
||||
import { PropertyFilter } from './services/property-filter';
|
||||
import { TaskTemplates } from './services/task-templates';
|
||||
import { ConfigValidator } from './services/config-validator';
|
||||
import { EnhancedConfigValidator } from './services/enhanced-config-validator';
|
||||
import { WorkflowValidator, WorkflowValidationResult } from './services/workflow-validator';
|
||||
|
||||
export class MCPEngine {
|
||||
private workflowValidator: WorkflowValidator;
|
||||
|
||||
constructor(private repository: NodeRepository) {
|
||||
this.workflowValidator = new WorkflowValidator(repository, EnhancedConfigValidator);
|
||||
}
|
||||
|
||||
async listNodes(args: any = {}) {
|
||||
return this.repository.getAllNodes(args.limit);
|
||||
}
|
||||
|
||||
async searchNodes(args: any) {
|
||||
return this.repository.searchNodes(args.query, args.mode || 'OR', args.limit || 20);
|
||||
}
|
||||
|
||||
async getNodeInfo(args: any) {
|
||||
return this.repository.getNodeByType(args.nodeType);
|
||||
}
|
||||
|
||||
async getNodeEssentials(args: any) {
|
||||
const node = await this.repository.getNodeByType(args.nodeType);
|
||||
if (!node) return null;
|
||||
|
||||
// Filter to essentials using static method
|
||||
const essentials = PropertyFilter.getEssentials(node.properties || [], args.nodeType);
|
||||
return {
|
||||
nodeType: node.nodeType,
|
||||
displayName: node.displayName,
|
||||
description: node.description,
|
||||
category: node.category,
|
||||
required: essentials.required,
|
||||
common: essentials.common
|
||||
};
|
||||
}
|
||||
|
||||
async getNodeDocumentation(args: any) {
|
||||
const node = await this.repository.getNodeByType(args.nodeType);
|
||||
return node?.documentation || null;
|
||||
}
|
||||
|
||||
async validateNodeOperation(args: any) {
|
||||
// Get node properties and validate
|
||||
const node = await this.repository.getNodeByType(args.nodeType);
|
||||
if (!node) {
|
||||
return {
|
||||
valid: false,
|
||||
errors: [{ type: 'invalid_configuration', property: '', message: 'Node type not found' }],
|
||||
warnings: [],
|
||||
suggestions: [],
|
||||
visibleProperties: [],
|
||||
hiddenProperties: []
|
||||
};
|
||||
}
|
||||
|
||||
return ConfigValidator.validate(args.nodeType, args.config, node.properties || []);
|
||||
}
|
||||
|
||||
async validateNodeMinimal(args: any) {
|
||||
// Get node and check minimal requirements
|
||||
const node = await this.repository.getNodeByType(args.nodeType);
|
||||
if (!node) {
|
||||
return { missingFields: [], error: 'Node type not found' };
|
||||
}
|
||||
|
||||
const missingFields: string[] = [];
|
||||
const requiredFields = PropertyFilter.getEssentials(node.properties || [], args.nodeType).required;
|
||||
|
||||
for (const field of requiredFields) {
|
||||
if (!args.config[field.name]) {
|
||||
missingFields.push(field.name);
|
||||
}
|
||||
}
|
||||
|
||||
return { missingFields };
|
||||
}
|
||||
|
||||
async searchNodeProperties(args: any) {
|
||||
return this.repository.searchNodeProperties(args.nodeType, args.query, args.maxResults || 20);
|
||||
}
|
||||
|
||||
async getNodeForTask(args: any) {
|
||||
return TaskTemplates.getTaskTemplate(args.task);
|
||||
}
|
||||
|
||||
async listAITools(args: any) {
|
||||
return this.repository.getAIToolNodes();
|
||||
}
|
||||
|
||||
async getDatabaseStatistics(args: any) {
|
||||
const count = await this.repository.getNodeCount();
|
||||
const aiTools = await this.repository.getAIToolNodes();
|
||||
return {
|
||||
totalNodes: count,
|
||||
aiToolsCount: aiTools.length,
|
||||
categories: ['trigger', 'transform', 'output', 'input']
|
||||
};
|
||||
}
|
||||
|
||||
async validateWorkflow(args: any): Promise<WorkflowValidationResult> {
|
||||
return this.workflowValidator.validateWorkflow(args.workflow, args.options);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user