UNPKG

@dollhousemcp/mcp-server

Version:

DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.

348 lines 13.8 kB
/** * OperationSchema - Declarative operation definitions for MCP-AQL * * This module provides schema-driven operation definitions that enable: * 1. Declarative operation configuration (no manual switch statements) * 2. Auto-generated parameter validation * 3. Type-safe dispatch to handler methods * 4. Single source of truth for operation metadata * * ARCHITECTURE: * Operations are defined with: * - endpoint: CRUDE endpoint (CREATE, READ, UPDATE, DELETE, EXECUTE) * - handler: Key in HandlerRegistry * - method: Method name on the handler * - params: Parameter definitions with types and mappings * - description: Human-readable description * * The SchemaDispatcher uses these definitions to automatically route * operations to handler methods without manual dispatch code. * * @see Issue #247 - Schema-driven operation definitions */ import type { CRUDEndpoint } from './OperationRouter.js'; /** * Primitive types supported in parameter schemas */ export type ParamType = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'string[]' | 'string | string[]' | 'unknown'; /** * Parameter definition in operation schema */ export interface ParamDef { /** Parameter type for validation */ type: ParamType; /** Whether the parameter is required (default: false) */ required?: boolean; /** Default value if not provided */ default?: unknown; /** Human-readable description */ description?: string; /** Maps input param name to handler arg name (if different) */ mapTo?: string; /** * Alternative sources to check for this parameter value. * Checked in order before falling back to the primary param name. * * Supports dot notation for nested access: * - 'input.elementType' - checks input.elementType * - 'params.type' - checks params.type (same as just checking the param) * * Use case: elementType can come from input.elementType OR params.type * * @example * type: { type: 'string', sources: ['input.elementType', 'params.type'] } */ sources?: string[]; } /** * Return type definition for introspection * @see Issue #254 - Auto-generate introspection from schema */ export interface ReturnTypeDef { /** Return type name (e.g., 'ElementList', 'SearchResult') */ name: string; /** Type kind for categorization */ kind: 'enum' | 'object' | 'scalar' | 'union'; /** Human-readable description of what is returned */ description: string; } /** * Parameter schema - map of parameter names to definitions */ export type ParamSchema = Record<string, ParamDef>; /** * Handler keys - these map to properties in HandlerRegistry */ export type HandlerKey = 'elementCRUD' | 'memoryManager' | 'agentManager' | 'templateRenderer' | 'elementQueryService' | 'collectionHandler' | 'portfolioHandler' | 'authHandler' | 'configHandler' | 'enhancedIndexHandler' | 'personaHandler' | 'syncHandler' | 'buildInfoService' | 'mcpAqlHandler' | 'cacheMemoryBudget'; /** * Complete operation schema definition */ export interface OperationDef { /** CRUDE endpoint this operation belongs to */ endpoint: CRUDEndpoint; /** Handler key in HandlerRegistry */ handler: HandlerKey; /** Method name to call on the handler */ method: string; /** Parameter definitions */ params?: ParamSchema; /** Human-readable description */ description: string; /** Whether the handler is optional (may not be configured) */ optional?: boolean; /** * Custom argument builder for complex cases: * - 'single': Pass params in schema order as positional args (default) * - 'spread': Pass (query, params) - for search-style operations * - 'named': Pass all params as a single named object * - 'namedWithType': Like 'named' but includes resolved 'type' param * - 'typeWithParams': Pass (type, fullParams) for operations needing type + pagination */ argBuilder?: 'single' | 'spread' | 'named' | 'namedWithType' | 'typeWithParams'; /** * Whether this operation needs access to the full OperationInput. * When true, SchemaDispatcher passes the full input for source resolution. * Required for operations that use param sources like 'input.elementType'. */ needsFullInput?: boolean; /** * Automatic parameter name conversion style. * - 'snakeToCamel': Convert snake_case params to camelCase for handler * * When set, all params are automatically converted before being passed * to the handler. Individual param `mapTo` overrides still take precedence. * * @example * // Input: { dry_run: true, max_results: 10 } * // Handler receives: { dryRun: true, maxResults: 10 } */ paramStyle?: 'snakeToCamel'; /** * Capability category for get_capabilities grouping. * Operations are grouped by user-intent categories in the capabilities map. * Operations without a category appear under "Other". * @see Issue #1760 - get_capabilities operation */ category?: string; /** * Return type information for introspection * @see Issue #254 - Auto-generate introspection from schema */ returns?: ReturnTypeDef; /** * Usage examples for introspection * @see Issue #254 - Auto-generate introspection from schema */ examples?: string[]; /** * Normalizer to use for parameter transformation. * * If specified, the normalizer is called before the handler method, * transforming raw input parameters into the format expected by the handler. * * Normalizers are registered in NormalizerRegistry and looked up by name. * * @see Issue #243 - Schema-driven normalizer architecture * * @example * // Use the search params normalizer * normalizer: 'searchParams' */ normalizer?: string; } /** * Complete operation schema - maps operation names to definitions */ export type OperationSchemaMap = Record<string, OperationDef>; /** * Collection operations schema * * These are the first operations migrated to schema-driven dispatch. * Each operation defines: * - Where it lives (endpoint) * - What handler to use * - What method to call * - What parameters it accepts */ export declare const COLLECTION_OPERATIONS: OperationSchemaMap; export declare const AUTH_OPERATIONS: OperationSchemaMap; export declare const ENHANCED_INDEX_OPERATIONS: OperationSchemaMap; export declare const TEMPLATE_OPERATIONS: OperationSchemaMap; export declare const INTROSPECTION_OPERATIONS: OperationSchemaMap; export declare const PERSONA_OPERATIONS: OperationSchemaMap; export declare const CONFIG_OPERATIONS: OperationSchemaMap; /** * Portfolio operations schema - demonstrates paramStyle conversion pattern. * * PATTERN: Automatic Parameter Style Conversion * External APIs often use snake_case naming, while JavaScript handlers * typically use camelCase. The `paramStyle: 'snakeToCamel'` setting * enables automatic conversion without individual `mapTo` definitions. * * This pattern is important for MCP-AQL adapters wrapping external MCP * servers that follow different naming conventions. * * @example * // Input from MCP client: { dry_run: true, max_results: 10 } * // Handler receives: { dryRun: true, maxResults: 10 } */ export declare const PORTFOLIO_OPERATIONS: OperationSchemaMap; /** * ElementCRUD operations schema - demonstrates input normalization pattern. * * PATTERN: Input Normalization * The 'type' parameter can come from two sources: * 1. input.elementType (top-level in OperationInput) * 2. params.type (inside the params object) * * The schema uses `sources` to define this fallback chain, and * `needsFullInput: true` tells SchemaDispatcher to provide full input access. * * This pattern is important for MCP-AQL adapters where external servers * may accept the same parameter in multiple locations. */ export declare const ELEMENT_CRUD_OPERATIONS: OperationSchemaMap; /** * Memory operations schema — introspection-only. * * These operations are dispatched via MCPAQLHandler.dispatchMemory() which * performs memory instance lookup by name. They cannot be routed through * SchemaDispatcher without extracting that pre-processing logic. * * @see Issue #594 - Document all MCP-AQL operations via schema */ export declare const MEMORY_SCHEMAS: OperationSchemaMap; /** * Execution lifecycle operations schema — introspection-only. * * These operations are dispatched via MCPAQLHandler.dispatchExecute() which * performs agent state management, autonomy evaluation, and resilience checks. * They cannot be routed through SchemaDispatcher without extracting that * complex pre-processing logic. * * @see Issue #594 - Document all MCP-AQL operations via schema */ export declare const EXECUTION_SCHEMAS: OperationSchemaMap; /** * Gatekeeper operations schema — introspection-only. * * These operations are dispatched via MCPAQLHandler.dispatchGatekeeper() which * performs session-level confirmation tracking and danger zone verification. * * @see Issue #594 - Document all MCP-AQL operations via schema */ export declare const GATEKEEPER_SCHEMAS: OperationSchemaMap; /** * Logging operations schema — introspection-only. * * Dispatched via MCPAQLHandler.dispatchLogging() with runtime parameter * validation via validateLogQueryParams(). * * @see Issue #594 - Document all MCP-AQL operations via schema */ export declare const LOGGING_SCHEMAS: OperationSchemaMap; /** * Metrics collection query schema — introspection-only. * * Dispatched via MCPAQLHandler.dispatchMetrics() which routes to * MemoryMetricsSink.query(). Follows the same pattern as query_logs. */ export declare const METRICS_SCHEMAS: OperationSchemaMap; /** * Activation lifecycle operations schema — introspection-only. * * These operations are dispatched via MCPAQLHandler.dispatchActivation() which * routes to ElementCRUDHandler activation strategies. They cannot be routed * through SchemaDispatcher without extracting that strategy-based dispatch logic. * * Issue #598: Activation state is now persisted per-session via ActivationStore. * Set DOLLHOUSE_SESSION_ID env var to isolate activation state between sessions. * * @see Issue #594 - Document all MCP-AQL operations via schema * @see Issue #598 - Per-session activation persistence */ export declare const ACTIVATION_SCHEMAS: OperationSchemaMap; /** * Search operations schema — introspection-only. * * These operations are dispatched via MCPAQLHandler.dispatchSearch() which * routes to ElementQueryService methods. They cannot be routed through * SchemaDispatcher without extracting that pre-processing logic. * * @see Issue #595 - Operation documentation coverage gate */ export declare const SEARCH_SCHEMAS: OperationSchemaMap; /** * Schema-driven operations — used by SchemaDispatcher for dispatch. * * Only operations that can be fully dispatched through SchemaDispatcher * belong here. Operations with complex pre-processing (memory lookup, * agent state management, gatekeeper sessions, log validation) are in * INTROSPECTION_ONLY_SCHEMAS instead. */ export declare const SCHEMA_DRIVEN_OPERATIONS: OperationSchemaMap; /** * Introspection-only schemas — metadata for operations dispatched by * legacy methods (dispatchMemory, dispatchExecute, dispatchGatekeeper, * dispatchLogging). These are NOT used for dispatch routing. * * @see Issue #594 - Document all MCP-AQL operations via schema */ /** * Browser operation schemas * @see Issue #774 - open portfolio browser */ export declare const BROWSER_SCHEMAS: OperationSchemaMap; export declare const INTROSPECTION_ONLY_SCHEMAS: OperationSchemaMap; /** * All operation schemas — union of dispatch-driven and introspection-only. * Used by IntrospectionResolver for complete operation documentation. * * @see Issue #594 - Document all MCP-AQL operations via schema */ export declare const ALL_OPERATION_SCHEMAS: OperationSchemaMap; /** * Check if an operation is schema-driven (used for SchemaDispatcher routing) */ export declare function isSchemaOperation(operation: string): boolean; /** * Get schema definition for a schema-driven operation (dispatch routing) */ export declare function getOperationSchema(operation: string): OperationDef | undefined; /** * Check if any operation schema exists (dispatch-driven or introspection-only) */ export declare function hasOperationSchema(operation: string): boolean; /** * Get schema for any operation (dispatch-driven or introspection-only) */ export declare function getAnyOperationSchema(operation: string): OperationDef | undefined; /** * Parameter info format used by IntrospectionResolver * This interface matches what IntrospectionResolver expects */ export interface ParameterInfo { name: string; type: string; required: boolean; description: string; default?: unknown; } /** * Convert ParamSchema to ParameterInfo array for introspection * * @param schema - The ParamSchema from an operation definition * @returns Array of ParameterInfo for IntrospectionResolver */ export declare function schemaToParameterInfo(schema: ParamSchema | undefined): ParameterInfo[]; /** * Get all schema-driven operations with their full definitions * Used by SchemaDispatcher to iterate over dispatchable operations */ export declare function getAllSchemaOperations(): Record<string, OperationDef>; /** * Get all operation schemas (dispatch-driven + introspection-only) * Used by IntrospectionResolver for complete operation documentation */ export declare function getAllOperationSchemas(): Record<string, OperationDef>; //# sourceMappingURL=OperationSchema.d.ts.map