๐งฉ RedQuanta MCP Plugin Development Guide¶
   **๐ Extend RedQuanta MCP with Custom Security Tools** *Complete guide to building, testing, and deploying custom plugins*
๐ฏ Plugin System Overview¶
๐๏ธ Architecture¶
๐งฉ REDQUANTA MCP PLUGIN ARCHITECTURE
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ก MCP Server Core โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ ๐ Plugin Manager โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโ โ
โ โ ๐ ๏ธ Core โ โ ๐ Web โ โ ๐ Auth โ โ ๐ AI โ โ
โ โ Tools โ โ Tools โ โ Tools โ โ Tools โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ ๐ Hot Reload Engine โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ ๐ก๏ธ Security Validation Layer โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ ๐ Schema Validation Engine โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โก Runtime Execution
๐ Key Features¶
| #### **๐ Hot Reloading** Add, update, or remove plugins without server restart | #### **๐ก๏ธ Security First** Built-in validation, sandboxing, and audit logging | #### **๐ Schema Validation** Automatic input/output validation with JSON Schema | #### **๐งช Testing Framework** Comprehensive testing tools and mock environments |
๐ Quick Start¶
โก Create Your First Plugin¶
๐ ๏ธ SSL Certificate Analyzer Example
#### **Step 1: Plugin Structure**plugins/ssl-analyzer/
โโโ manifest.json # Plugin metadata
โโโ index.ts # Main plugin code
โโโ schemas/ # Input/output schemas
โ โโโ input.json
โ โโโ output.json
โโโ tests/ # Test files
โ โโโ ssl-analyzer.test.ts
โ โโโ fixtures/
โโโ README.md # Plugin documentation
{
"name": "ssl_analyzer",
"version": "1.0.0",
"description": "Advanced SSL/TLS certificate analysis tool",
"author": "Your Name <your.email@domain.com>",
"category": "web",
"dangerLevel": "safe",
"keywords": ["ssl", "tls", "certificate", "security"],
"entryPoint": "index.ts",
"inputSchema": "schemas/input.json",
"outputSchema": "schemas/output.json",
"permissions": {
"network": true,
"filesystem": false,
"dangerous": false
},
"dependencies": {
"node-forge": "^1.3.1",
"tls-scanner": "^2.1.0"
},
"minimumVersion": "0.3.0",
"license": "MIT"
}
import { ToolWrapper, ToolResult, SecurityContext } from '@redquanta/plugin-api';
import * as forge from 'node-forge';
import { TLSScanner } from 'tls-scanner';
/**
* SSL/TLS Certificate Analyzer Plugin
*
* @plugin ssl_analyzer
* @version 1.0.0
* @category web
* @danger_level safe
*/
export default class SSLAnalyzerTool extends ToolWrapper {
public readonly name = 'ssl_analyzer';
public readonly description = 'Comprehensive SSL/TLS certificate analysis';
public readonly category = 'web';
public readonly dangerLevel = 'safe';
/**
* Execute SSL analysis
*/
async execute(options: SSLAnalysisOptions, context: SecurityContext): Promise<ToolResult> {
try {
// Validate input
this.validateInput(options);
// Initialize progress tracking
const progressTracker = context.getProgressTracker();
progressTracker.start('SSL Analysis', 4);
// Phase 1: Certificate Discovery
progressTracker.updatePhase('Discovering certificates');
const certificates = await this.discoverCertificates(options.target);
progressTracker.incrementPhase();
// Phase 2: Certificate Analysis
progressTracker.updatePhase('Analyzing certificate chain');
const chainAnalysis = await this.analyzeCertificateChain(certificates);
progressTracker.incrementPhase();
// Phase 3: Security Assessment
progressTracker.updatePhase('Performing security assessment');
const securityAnalysis = await this.performSecurityAnalysis(options.target);
progressTracker.incrementPhase();
// Phase 4: Generate Report
progressTracker.updatePhase('Generating report');
const report = await this.generateReport(chainAnalysis, securityAnalysis);
progressTracker.complete();
return {
success: true,
data: {
target: options.target,
certificates: chainAnalysis,
security: securityAnalysis,
recommendations: this.generateRecommendations(securityAnalysis)
},
metadata: {
version: this.version,
analysisDate: new Date().toISOString(),
toolchain: 'node-forge + tls-scanner'
}
};
} catch (error) {
this.logger.error('SSL analysis failed', { error: error.message, target: options.target });
return {
success: false,
error: {
code: 'ANALYSIS_FAILED',
message: `SSL analysis failed: ${error.message}`,
details: error.stack
}
};
}
}
/**
* Discover SSL certificates
*/
private async discoverCertificates(target: string): Promise<Certificate[]> {
const scanner = new TLSScanner();
const results = await scanner.scan(target, {
port: 443,
timeout: 30000,
protocols: ['TLSv1.2', 'TLSv1.3'],
includeCipherSuites: true
});
return results.certificates.map(cert => ({
subject: cert.subject,
issuer: cert.issuer,
serialNumber: cert.serialNumber,
notBefore: cert.validFrom,
notAfter: cert.validTo,
fingerprint: cert.fingerprint,
publicKey: this.analyzePublicKey(cert.publicKey),
extensions: this.analyzeExtensions(cert.extensions)
}));
}
/**
* Analyze certificate chain
*/
private async analyzeCertificateChain(certificates: Certificate[]): Promise<ChainAnalysis> {
const chain = this.buildCertificateChain(certificates);
return {
length: chain.length,
rootCA: chain[chain.length - 1]?.issuer,
intermediates: chain.slice(1, -1).map(cert => cert.subject),
leafCertificate: chain[0],
validation: {
chainValid: await this.validateChain(chain),
trustStore: await this.checkTrustStore(chain),
ocspStatus: await this.checkOCSP(chain[0]),
crlStatus: await this.checkCRL(chain[0])
}
};
}
/**
* Perform comprehensive security analysis
*/
private async performSecurityAnalysis(target: string): Promise<SecurityAnalysis> {
const scanner = new TLSScanner();
const results = await scanner.securityScan(target, {
checkVulnerabilities: true,
checkConfiguration: true,
checkCompliance: true
});
return {
protocolSupport: results.protocols,
cipherSuites: results.cipherSuites,
keyExchange: results.keyExchange,
vulnerabilities: this.mapVulnerabilities(results.vulnerabilities),
configuration: {
hsts: results.headers.hsts,
hpkp: results.headers.hpkp,
certificateTransparency: results.ct?.enabled,
ocspStapling: results.ocsp?.stapling
},
compliance: {
pciDss: this.checkPCIDSSCompliance(results),
soc2: this.checkSOC2Compliance(results),
nist: this.checkNISTCompliance(results)
}
};
}
/**
* Generate actionable recommendations
*/
private generateRecommendations(analysis: SecurityAnalysis): Recommendation[] {
const recommendations: Recommendation[] = [];
// Check for weak protocols
if (analysis.protocolSupport.includes('TLSv1.0') || analysis.protocolSupport.includes('TLSv1.1')) {
recommendations.push({
severity: 'high',
category: 'protocol',
title: 'Disable Weak TLS Versions',
description: 'TLS 1.0 and 1.1 are deprecated and should be disabled',
remediation: 'Configure server to only support TLS 1.2 and 1.3',
references: ['https://tools.ietf.org/rfc/rfc8996.txt']
});
}
// Check for weak cipher suites
const weakCiphers = analysis.cipherSuites.filter(cipher =>
cipher.includes('DES') || cipher.includes('RC4') || cipher.includes('MD5')
);
if (weakCiphers.length > 0) {
recommendations.push({
severity: 'medium',
category: 'encryption',
title: 'Remove Weak Cipher Suites',
description: `Found ${weakCiphers.length} weak cipher suites`,
remediation: 'Configure server to use only strong, modern cipher suites',
details: { weakCiphers }
});
}
// Check for missing security headers
if (!analysis.configuration.hsts) {
recommendations.push({
severity: 'medium',
category: 'headers',
title: 'Enable HTTP Strict Transport Security (HSTS)',
description: 'HSTS header is missing, allowing potential downgrade attacks',
remediation: 'Add "Strict-Transport-Security" header to all HTTPS responses'
});
}
return recommendations;
}
/**
* Get tool schema for validation and documentation
*/
getSchema(): ToolSchema {
return {
input: {
type: 'object',
properties: {
target: {
type: 'string',
description: 'Target hostname or IP address',
pattern: '^[a-zA-Z0-9.-]+$',
examples: ['example.com', '192.168.1.1']
},
port: {
type: 'integer',
description: 'Target port number',
default: 443,
minimum: 1,
maximum: 65535
},
detailed: {
type: 'boolean',
description: 'Perform detailed analysis including vulnerability checks',
default: false
}
},
required: ['target']
},
output: {
type: 'object',
properties: {
certificates: {
type: 'object',
description: 'Certificate chain analysis results'
},
security: {
type: 'object',
description: 'Security configuration analysis'
},
recommendations: {
type: 'array',
description: 'Security recommendations'
}
}
}
};
}
}
// Type definitions
interface SSLAnalysisOptions {
target: string;
port?: number;
detailed?: boolean;
}
interface Certificate {
subject: string;
issuer: string;
serialNumber: string;
notBefore: Date;
notAfter: Date;
fingerprint: string;
publicKey: PublicKeyInfo;
extensions: CertificateExtension[];
}
interface SecurityAnalysis {
protocolSupport: string[];
cipherSuites: string[];
keyExchange: KeyExchangeInfo;
vulnerabilities: Vulnerability[];
configuration: SecurityConfiguration;
compliance: ComplianceStatus;
}
interface Recommendation {
severity: 'low' | 'medium' | 'high' | 'critical';
category: string;
title: string;
description: string;
remediation: string;
references?: string[];
details?: any;
}
๐ Plugin API Reference¶
๐ Base Classes¶
๐๏ธ ToolWrapper Base Class
/**
* Base class for all RedQuanta MCP plugins
*/
abstract class ToolWrapper {
// Required properties
abstract readonly name: string;
abstract readonly description: string;
abstract readonly category: string;
abstract readonly dangerLevel: 'safe' | 'caution' | 'dangerous';
// Optional properties
readonly version?: string;
readonly author?: string;
readonly keywords?: string[];
// Core methods that must be implemented
abstract execute(
options: any,
context: SecurityContext
): Promise<ToolResult>;
abstract getSchema(): ToolSchema;
// Optional lifecycle methods
async initialize?(config: PluginConfig): Promise<void>;
async cleanup?(): Promise<void>;
async validateInput?(input: any): Promise<ValidationResult>;
// Utility methods provided by base class
protected validateInput(input: any, schema?: JSONSchema): ValidationResult;
protected createProgressTracker(phases: string[]): ProgressTracker;
protected getLogger(): Logger;
protected getCacheManager(): CacheManager;
protected getFileSystem(): SecureFileSystem;
}
๐ก๏ธ Security Context¶
๐ SecurityContext Interface
interface SecurityContext {
// User information
userId: string;
permissions: Permission[];
dangerousMode: boolean;
// Execution environment
jailRoot: string;
workingDirectory: string;
environmentVariables: Record<string, string>;
// Security controls
timeoutMs: number;
maxMemoryMb: number;
allowedNetworkPorts: number[];
// Utility services
getProgressTracker(): ProgressTracker;
getLogger(): Logger;
getFileSystem(): SecureFileSystem;
getCacheManager(): CacheManager;
getCommandRunner(): CommandRunner;
// Validation methods
validateTarget(target: string): ValidationResult;
validatePort(port: number): ValidationResult;
checkPermission(permission: string): boolean;
}
interface Permission {
name: string;
scope: string;
level: 'read' | 'write' | 'execute' | 'admin';
}
๐ Data Structures¶
๐ Core Interfaces
interface ToolResult {
success: boolean;
data?: any;
error?: {
code: string;
message: string;
details?: any;
};
metadata?: {
executionTime?: number;
memoryUsed?: number;
cached?: boolean;
version?: string;
[key: string]: any;
};
}
interface ToolSchema {
input: JSONSchema;
output: JSONSchema;
examples?: Example[];
documentation?: Documentation;
}
interface Example {
name: string;
description: string;
input: any;
expectedOutput: any;
}
interface Documentation {
usage: string;
parameters: ParameterDoc[];
returns: string;
examples: string[];
seeAlso: string[];
}
interface ParameterDoc {
name: string;
type: string;
description: string;
required: boolean;
default?: any;
constraints?: any;
}
๐งช Testing Framework¶
โ Unit Testing¶
๐ฌ Plugin Test Suite
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { PluginTestFramework, MockSecurityContext } from '@redquanta/testing';
import SSLAnalyzerTool from '../index';
describe('SSLAnalyzerTool', () => {
let plugin: SSLAnalyzerTool;
let mockContext: MockSecurityContext;
let testFramework: PluginTestFramework;
beforeEach(async () => {
testFramework = new PluginTestFramework();
mockContext = testFramework.createMockContext({
userId: 'test-user',
permissions: ['network:read'],
dangerousMode: false
});
plugin = new SSLAnalyzerTool();
await plugin.initialize?.(testFramework.getDefaultConfig());
});
afterEach(async () => {
await plugin.cleanup?.();
testFramework.cleanup();
});
describe('Input Validation', () => {
it('should validate target hostname', async () => {
const validInput = { target: 'example.com' };
const result = await plugin.validateInput?.(validInput);
expect(result.valid).toBe(true);
});
it('should reject invalid hostname', async () => {
const invalidInput = { target: 'invalid..hostname' };
const result = await plugin.validateInput?.(invalidInput);
expect(result.valid).toBe(false);
expect(result.errors).toContain('Invalid hostname format');
});
it('should validate port range', async () => {
const validInput = { target: 'example.com', port: 443 };
const invalidInput = { target: 'example.com', port: 70000 };
expect((await plugin.validateInput?.(validInput))?.valid).toBe(true);
expect((await plugin.validateInput?.(invalidInput))?.valid).toBe(false);
});
});
describe('SSL Analysis', () => {
it('should analyze valid SSL certificate', async () => {
// Use test framework's mock SSL server
const mockServer = testFramework.createMockSSLServer({
certificate: testFramework.generateTestCertificate(),
port: 8443
});
await mockServer.start();
try {
const result = await plugin.execute(
{ target: 'localhost', port: 8443 },
mockContext
);
expect(result.success).toBe(true);
expect(result.data.certificates).toBeDefined();
expect(result.data.security).toBeDefined();
expect(result.data.recommendations).toBeInstanceOf(Array);
} finally {
await mockServer.stop();
}
});
it('should handle connection timeout', async () => {
const result = await plugin.execute(
{ target: 'nonexistent.invalid' },
mockContext
);
expect(result.success).toBe(false);
expect(result.error?.code).toBe('CONNECTION_TIMEOUT');
});
it('should detect weak SSL configuration', async () => {
const mockServer = testFramework.createMockSSLServer({
certificate: testFramework.generateTestCertificate(),
cipherSuites: ['TLS_RSA_WITH_DES_CBC_SHA'], // Weak cipher
protocols: ['TLSv1.0'] // Weak protocol
});
await mockServer.start();
try {
const result = await plugin.execute(
{ target: 'localhost', port: mockServer.port },
mockContext
);
expect(result.success).toBe(true);
expect(result.data.recommendations).toHaveLength(2); // Weak protocol + weak cipher
expect(result.data.recommendations[0].severity).toBe('high');
} finally {
await mockServer.stop();
}
});
});
describe('Security Compliance', () => {
it('should check PCI DSS compliance', async () => {
const mockServer = testFramework.createMockSSLServer({
certificate: testFramework.generateTestCertificate(),
pciCompliant: false
});
await mockServer.start();
try {
const result = await plugin.execute(
{ target: 'localhost', port: mockServer.port, detailed: true },
mockContext
);
expect(result.data.security.compliance.pciDss).toBe(false);
} finally {
await mockServer.stop();
}
});
});
describe('Performance', () => {
it('should complete analysis within timeout', async () => {
const startTime = Date.now();
const result = await plugin.execute(
{ target: 'google.com' },
mockContext
);
const duration = Date.now() - startTime;
expect(result.success).toBe(true);
expect(duration).toBeLessThan(30000); // 30 second timeout
});
it('should cache results appropriately', async () => {
const target = 'example.com';
// First execution
const result1 = await plugin.execute({ target }, mockContext);
expect(result1.metadata?.cached).toBe(false);
// Second execution (should be cached)
const result2 = await plugin.execute({ target }, mockContext);
expect(result2.metadata?.cached).toBe(true);
});
});
});
๐๏ธ Integration Testing¶
๐ End-to-End Tests
import { describe, it, expect } from 'vitest';
import { RedQuantaTestServer, APIClient } from '@redquanta/testing';
describe('SSL Analyzer Integration', () => {
let server: RedQuantaTestServer;
let client: APIClient;
beforeAll(async () => {
server = new RedQuantaTestServer();
await server.start();
// Load the SSL analyzer plugin
await server.loadPlugin('./plugins/ssl-analyzer');
client = new APIClient(server.url);
});
afterAll(async () => {
await server.stop();
});
it('should be available in tool list', async () => {
const tools = await client.getTools();
expect(tools.tools).toContainEqual(
expect.objectContaining({
name: 'ssl_analyzer',
category: 'web',
dangerous: false
})
);
});
it('should execute via REST API', async () => {
const result = await client.executeTool('ssl_analyzer', {
target: 'google.com'
});
expect(result.success).toBe(true);
expect(result.data.certificates).toBeDefined();
});
it('should execute via MCP protocol', async () => {
const mcpClient = server.getMCPClient();
const result = await mcpClient.callTool('ssl_analyzer', {
target: 'github.com'
});
expect(result.content[0].type).toBe('text');
expect(JSON.parse(result.content[0].text).success).toBe(true);
});
});
๐จ Advanced Features¶
๐ Hot Reloading¶
โก Dynamic Plugin Management
// Plugin Manager API
class PluginManager {
/**
* Load a plugin at runtime
*/
async loadPlugin(pluginPath: string): Promise<LoadResult> {
try {
// Validate plugin structure
const manifest = await this.validatePluginManifest(pluginPath);
// Security scan
await this.securityScanPlugin(pluginPath);
// Load and instantiate
const PluginClass = await import(path.join(pluginPath, manifest.entryPoint));
const instance = new PluginClass.default();
// Initialize
await instance.initialize?.(this.getPluginConfig(manifest));
// Register
this.registeredPlugins.set(manifest.name, {
instance,
manifest,
loadedAt: new Date()
});
this.logger.info('Plugin loaded successfully', {
name: manifest.name,
version: manifest.version
});
return { success: true, plugin: manifest };
} catch (error) {
this.logger.error('Failed to load plugin', { error: error.message });
return { success: false, error: error.message };
}
}
/**
* Reload a plugin without server restart
*/
async reloadPlugin(pluginName: string): Promise<ReloadResult> {
const existing = this.registeredPlugins.get(pluginName);
if (!existing) {
throw new Error(`Plugin ${pluginName} not found`);
}
// Cleanup existing instance
await existing.instance.cleanup?.();
// Clear module cache
this.clearModuleCache(existing.manifest.entryPoint);
// Reload
const result = await this.loadPlugin(existing.manifest.path);
if (result.success) {
this.emit('plugin:reloaded', { name: pluginName });
}
return result;
}
/**
* Unload a plugin
*/
async unloadPlugin(pluginName: string): Promise<void> {
const plugin = this.registeredPlugins.get(pluginName);
if (plugin) {
await plugin.instance.cleanup?.();
this.registeredPlugins.delete(pluginName);
this.emit('plugin:unloaded', { name: pluginName });
}
}
}
// Usage in development
const pluginManager = new PluginManager();
// Watch for file changes and hot reload
import chokidar from 'chokidar';
chokidar.watch('./plugins/**/*').on('change', async (filePath) => {
const pluginName = this.extractPluginName(filePath);
if (pluginName && this.registeredPlugins.has(pluginName)) {
console.log(`๐ Reloading plugin: ${pluginName}`);
await pluginManager.reloadPlugin(pluginName);
console.log(`โ
Plugin reloaded: ${pluginName}`);
}
});
๐ง AI-Enhanced Plugins¶
๐ค LLM Integration Example
import { ToolWrapper, SecurityContext, ToolResult } from '@redquanta/plugin-api';
import { OpenAI } from 'openai';
/**
* AI-powered vulnerability analyzer
*/
export default class AIVulnAnalyzer extends ToolWrapper {
public readonly name = 'ai_vuln_analyzer';
public readonly description = 'AI-powered vulnerability analysis and remediation suggestions';
public readonly category = 'ai';
public readonly dangerLevel = 'safe';
private openai: OpenAI;
async initialize(config: PluginConfig): Promise<void> {
this.openai = new OpenAI({
apiKey: config.openaiApiKey,
organization: config.openaiOrg
});
}
async execute(options: AIAnalysisOptions, context: SecurityContext): Promise<ToolResult> {
const { scanResults, target } = options;
try {
// Prepare context for AI analysis
const analysisContext = this.prepareScanContext(scanResults);
// Generate AI analysis
const aiAnalysis = await this.generateAIAnalysis(analysisContext, target);
// Generate remediation suggestions
const remediation = await this.generateRemediationPlan(aiAnalysis, scanResults);
// Risk assessment
const riskAssessment = await this.performRiskAssessment(aiAnalysis);
return {
success: true,
data: {
analysis: aiAnalysis,
remediation: remediation,
riskAssessment: riskAssessment,
confidence: this.calculateConfidence(aiAnalysis),
actionPlan: this.generateActionPlan(remediation)
},
metadata: {
model: 'gpt-4',
tokensUsed: aiAnalysis.tokensUsed,
analysisDate: new Date().toISOString()
}
};
} catch (error) {
return {
success: false,
error: {
code: 'AI_ANALYSIS_FAILED',
message: error.message
}
};
}
}
private async generateAIAnalysis(context: string, target: string): Promise<AIAnalysis> {
const prompt = `
You are a senior cybersecurity analyst reviewing scan results for ${target}.
Scan Results:
${context}
Please provide:
1. Executive summary of security posture
2. Critical vulnerabilities requiring immediate attention
3. Risk assessment with business impact
4. Attack vectors and exploitation likelihood
5. Compliance implications
Format your response as structured JSON.
`;
const response = await this.openai.chat.completions.create({
model: 'gpt-4',
messages: [
{
role: 'system',
content: 'You are an expert cybersecurity analyst specializing in vulnerability assessment and risk analysis.'
},
{
role: 'user',
content: prompt
}
],
temperature: 0.1,
max_tokens: 2000
});
return {
summary: response.choices[0].message.content,
tokensUsed: response.usage?.total_tokens,
model: 'gpt-4'
};
}
private async generateRemediationPlan(analysis: AIAnalysis, scanResults: any): Promise<RemediationPlan> {
const prompt = `
Based on the security analysis and scan results, create a detailed remediation plan.
Analysis: ${analysis.summary}
Provide:
1. Prioritized list of actions (Critical, High, Medium, Low)
2. Specific technical steps for each remediation
3. Estimated effort and timeline
4. Resource requirements
5. Validation steps
Return as structured JSON with clear action items.
`;
const response = await this.openai.chat.completions.create({
model: 'gpt-4',
messages: [{ role: 'user', content: prompt }],
temperature: 0.1,
max_tokens: 1500
});
return JSON.parse(response.choices[0].message.content || '{}');
}
getSchema(): ToolSchema {
return {
input: {
type: 'object',
properties: {
scanResults: {
type: 'object',
description: 'Results from previous security scans'
},
target: {
type: 'string',
description: 'Target system being analyzed'
},
analysisDepth: {
type: 'string',
enum: ['quick', 'standard', 'comprehensive'],
default: 'standard'
}
},
required: ['scanResults', 'target']
},
output: {
type: 'object',
properties: {
analysis: { type: 'object' },
remediation: { type: 'object' },
riskAssessment: { type: 'object' },
actionPlan: { type: 'array' }
}
}
};
}
}
๐ Performance Monitoring¶
๐ Plugin Performance Tracking
import { EventEmitter } from 'events';
/**
* Performance monitoring decorator for plugins
*/
export function MonitorPerformance(config: MonitoringConfig = {}) {
return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {
const method = descriptor.value;
descriptor.value = async function (...args: any[]) {
const startTime = process.hrtime.bigint();
const startMemory = process.memoryUsage();
try {
const result = await method.apply(this, args);
// Collect metrics
const endTime = process.hrtime.bigint();
const endMemory = process.memoryUsage();
const metrics = {
executionTime: Number(endTime - startTime) / 1000000, // ms
memoryDelta: endMemory.heapUsed - startMemory.heapUsed,
timestamp: new Date().toISOString(),
method: propertyName,
success: result.success
};
// Report metrics
this.reportMetrics?.(metrics);
return result;
} catch (error) {
// Report error metrics
const endTime = process.hrtime.bigint();
this.reportMetrics?.({
executionTime: Number(endTime - startTime) / 1000000,
timestamp: new Date().toISOString(),
method: propertyName,
success: false,
error: error.message
});
throw error;
}
};
return descriptor;
};
}
// Usage in plugin
export default class MonitoredPlugin extends ToolWrapper {
@MonitorPerformance()
async execute(options: any, context: SecurityContext): Promise<ToolResult> {
// Plugin implementation
return { success: true, data: {} };
}
private reportMetrics(metrics: PerformanceMetrics): void {
// Send to monitoring system
const monitor = this.getMonitoringService();
monitor.recordMetrics(this.name, metrics);
}
}
๐ฆ Plugin Distribution¶
๐ Publishing Plugins¶
๐ Publication Process
#### **1. Plugin Registry Structure**// registry.json
{
"plugins": [
{
"name": "ssl_analyzer",
"version": "1.0.0",
"author": "Your Name",
"description": "Advanced SSL/TLS certificate analysis",
"category": "web",
"dangerLevel": "safe",
"downloadUrl": "https://github.com/username/redquanta-ssl-analyzer/releases/download/v1.0.0/ssl-analyzer.tar.gz",
"checksum": "sha256:abc123...",
"dependencies": {
"node-forge": "^1.3.1"
},
"minimumVersion": "0.3.0",
"tags": ["ssl", "tls", "certificate", "security"],
"license": "MIT",
"homepage": "https://github.com/username/redquanta-ssl-analyzer",
"repository": "https://github.com/username/redquanta-ssl-analyzer.git"
}
]
}
# .github/workflows/publish-plugin.yml
name: Publish Plugin
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install dependencies
run: pnpm install
- name: Run tests
run: pnpm test
- name: Build plugin
run: pnpm build
- name: Package plugin
run: |
tar -czf ssl-analyzer.tar.gz \
manifest.json \
dist/ \
schemas/ \
README.md \
LICENSE
- name: Generate checksums
run: sha256sum ssl-analyzer.tar.gz > checksums.txt
- name: Upload to registry
run: |
curl -X POST \
-H "Authorization: Bearer ${{ secrets.REGISTRY_TOKEN }}" \
-F "plugin=@ssl-analyzer.tar.gz" \
-F "manifest=@manifest.json" \
https://registry.redquanta.dev/plugins/upload
# Install from registry
redquanta-cli plugin install ssl_analyzer
# Install from URL
redquanta-cli plugin install https://github.com/user/plugin/releases/download/v1.0.0/plugin.tar.gz
# Install from local file
redquanta-cli plugin install ./ssl-analyzer.tar.gz
# List installed plugins
redquanta-cli plugin list
# Update plugin
redquanta-cli plugin update ssl_analyzer
# Remove plugin
redquanta-cli plugin remove ssl_analyzer
๐ Plugin Security¶
๐ก๏ธ Security Validation Pipeline
/**
* Plugin security scanner
*/
class PluginSecurityScanner {
async scanPlugin(pluginPath: string): Promise<SecurityScanResult> {
const results: SecurityIssue[] = [];
// 1. Static code analysis
const codeIssues = await this.analyzeCode(pluginPath);
results.push(...codeIssues);
// 2. Dependency vulnerability scan
const depIssues = await this.scanDependencies(pluginPath);
results.push(...depIssues);
// 3. Permission analysis
const permIssues = await this.analyzePermissions(pluginPath);
results.push(...permIssues);
// 4. Sandbox escape detection
const sandboxIssues = await this.detectSandboxEscape(pluginPath);
results.push(...sandboxIssues);
return {
safe: results.length === 0,
issues: results,
riskLevel: this.calculateRiskLevel(results)
};
}
private async analyzeCode(pluginPath: string): Promise<SecurityIssue[]> {
const issues: SecurityIssue[] = [];
const files = glob.sync('**/*.{ts,js}', { cwd: pluginPath });
for (const file of files) {
const content = fs.readFileSync(path.join(pluginPath, file), 'utf8');
// Check for dangerous patterns
if (content.includes('eval(') || content.includes('new Function(')) {
issues.push({
severity: 'high',
type: 'code_injection',
message: 'Dynamic code execution detected',
file,
line: this.findLineNumber(content, /eval\(|new Function\(/),
remediation: 'Remove dynamic code execution'
});
}
// Check for filesystem access outside jail
if (content.includes('process.cwd()') || content.includes('../')) {
issues.push({
severity: 'medium',
type: 'path_traversal',
message: 'Potential path traversal detected',
file
});
}
// Check for network access without permission
if (content.includes('require(\'http\')') && !this.hasNetworkPermission(pluginPath)) {
issues.push({
severity: 'medium',
type: 'unauthorized_network',
message: 'Network access without permission',
file
});
}
}
return issues;
}
private async scanDependencies(pluginPath: string): Promise<SecurityIssue[]> {
const packageJson = JSON.parse(
fs.readFileSync(path.join(pluginPath, 'package.json'), 'utf8')
);
const auditResult = await this.runNpmAudit(packageJson.dependencies);
return auditResult.vulnerabilities.map(vuln => ({
severity: vuln.severity,
type: 'vulnerable_dependency',
message: `Vulnerable dependency: ${vuln.module_name}`,
remediation: `Update to ${vuln.patched_versions}`
}));
}
}
๐ Support & Resources¶
๐ Getting Help¶
[](https://github.com/sc4rfurry/RedQuanta-MCP/issues/new?template=plugin_issue.md) [](https://github.com/sc4rfurry/RedQuanta-MCP/discussions/categories/plugin-development) [](https://registry.redquanta.dev)
๐ Resources¶
| #### **๐ Documentation** - [Plugin API Reference](API_REFERENCE.md) - [Testing Guide](TESTING_GUIDE.md) - [Best Practices](BEST_PRACTICES.md) - [Security Guidelines](SECURITY_GUIDELINES.md) | #### **๐ ๏ธ Tools** - [Plugin Template](../templates/plugin-template/) - [Testing Framework](../testing/plugin-testing/) - [CLI Tools](../../scripts/plugin-tools/) - [Registry CLI](../../cli/plugin-registry/) | #### **๐ค Community** - [Plugin Developers Forum](https://github.com/sc4rfurry/RedQuanta-MCP/discussions/categories/plugin-development) - [Example Plugins](../../examples/plugins/) - [Community Registry](https://registry.redquanta.dev) - [Plugin Showcase](https://github.com/sc4rfurry/RedQuanta-MCP/wiki/Plugin-Showcase) |
**๐งฉ Plugin Development Guide v1.0**    **Made with ๐งฉ by [@sc4rfurry](https://github.com/sc4rfurry)** *Extend RedQuanta MCP with powerful custom tools* --- **๐ Quick Navigation**: [๐ Documentation Home](../README.md) โข [๐ก API Reference](../api/REST_API.md) โข [๐งช Testing Guide](TESTING_GUIDE.md) โข [โ Get Help](https://github.com/sc4rfurry/RedQuanta-MCP/discussions)