Jake Shore f3c4cd817b Add all MCP servers + factory infra to MCPEngine — 2026-02-06
=== NEW SERVERS ADDED (7) ===
- servers/closebot — 119 tools, 14 modules, 4,656 lines TS (Stage 7)
- servers/google-console — Google Search Console MCP (Stage 7)
- servers/meta-ads — Meta/Facebook Ads MCP (Stage 8)
- servers/twilio — Twilio communications MCP (Stage 8)
- servers/competitor-research — Competitive intel MCP (Stage 6)
- servers/n8n-apps — n8n workflow MCP apps (Stage 6)
- servers/reonomy — Commercial real estate MCP (Stage 1)

=== FACTORY INFRASTRUCTURE ADDED ===
- infra/factory-tools — mcp-jest, mcp-validator, mcp-add, MCP Inspector
  - 60 test configs, 702 auto-generated test cases
  - All 30 servers score 100/100 protocol compliance
- infra/command-center — Pipeline state, operator playbook, dashboard config
- infra/factory-reviews — Automated eval reports

=== DOCS ADDED ===
- docs/MCP-FACTORY.md — Factory overview
- docs/reports/ — 5 pipeline evaluation reports
- docs/research/ — Browser MCP research

=== RULES ESTABLISHED ===
- CONTRIBUTING.md — All MCP work MUST go in this repo
- README.md — Full inventory of 37 servers + infra docs
- .gitignore — Updated for Python venvs

TOTAL: 37 MCP servers + full factory pipeline in one repo.
This is now the single source of truth for all MCP work.
2026-02-06 06:32:29 -05:00

100 lines
2.7 KiB
TypeScript

/**
* Base class for all tool packs.
* Extend this to create a new pack with tools and apps.
*/
import { z } from 'zod';
import type { TwilioClient } from '../client.js';
import type { RegisteredTool, SafetyTier, ToolAnnotations, ToolResult } from '../tool-registry.js';
import { appResult } from '../apps/renderer.js';
export abstract class BasePack {
protected client: TwilioClient;
protected tools: RegisteredTool[] = [];
/** Pack identifier (e.g., 'messaging', 'voice') */
abstract readonly name: string;
/** Human-readable description */
abstract readonly description: string;
/** Keywords for intent detection / lazy loading */
abstract readonly keywords: string[];
constructor(client: TwilioClient) {
this.client = client;
}
/** Override this to register all tools in the pack */
abstract setup(): void;
/** Get all registered tools */
getTools(): RegisteredTool[] {
return this.tools;
}
/** Helper to register a tool with less boilerplate */
protected registerTool(config: {
name: string;
description: string;
category: string;
safety: SafetyTier;
annotations?: Partial<ToolAnnotations>;
inputSchema: z.ZodType<any>;
_meta?: {
labels: {
category: string;
access: "read" | "write" | "delete";
complexity: "simple" | "complex" | "batch";
};
};
isApp?: boolean;
tier?: 1 | 2;
handler: (params: any) => Promise<ToolResult>;
}): void {
this.tools.push({
name: config.name,
description: config.description,
category: config.category,
pack: this.name,
safety: config.safety,
annotations: {
readOnlyHint: config.safety === 'green',
destructiveHint: false,
idempotentHint: false,
costHint: false,
...config.annotations,
},
inputSchema: config.inputSchema,
_meta: config._meta,
isApp: config.isApp ?? false,
tier: config.tier ?? 2,
handler: config.handler,
});
}
/** Helper: return a text-only result */
protected textResult(text: string, isError = false): ToolResult {
return {
content: [{ type: 'text', text }],
isError,
};
}
/** Helper: return an error result */
protected errorResult(message: string): ToolResult {
return this.textResult(`Error: ${message}`, true);
}
/** Helper: return a JSON result */
protected jsonResult(data: any, summary?: string): ToolResult {
const text = summary
? `${summary}\n\n${JSON.stringify(data, null, 2)}`
: JSON.stringify(data, null, 2);
return { content: [{ type: 'text', text }] };
}
/** Helper: return an MCP App (HTML) result */
protected appResult(html: string, textFallback: string): ToolResult {
return appResult(html, textFallback);
}
}