# Persona Content Pack Design Document
## Overview
This document specifies the design for a persona content loading system for hypertool-mcp. A "persona" is a configurable bundle that defines toolsets and MCP server configurations, allowing users to quickly switch between different development contexts and tool configurations.
## Table of Contents
1. [Requirements](#requirements)
2. [Architecture Design](#architecture-design)
3. [Schema Definitions](#schema-definitions)
4. [File System Structure](#file-system-structure)
5. [Implementation Components](#implementation-components)
6. [Validation Strategy](#validation-strategy)
7. [Integration Points](#integration-points)
8. [API Surface](#api-surface)
9. [Error Handling](#error-handling)
10. [Future Enhancements](#future-enhancements)
## Requirements
### Core Requirements
1. **Named Folder Structure**: Each persona is contained in a folder that matches the persona's name in its metadata
2. **Required Configuration File**: Each persona folder must contain a `persona.yaml` or `persona.yml` file
3. **Optional MCP Configuration**: Personas may include an `mcp.json` file following the standard MCP config format
4. **Future Archive Support**: Personas will support compression into `.htp` (HyperTool Persona) ZIP archives
5. **Asset Bundling**: Future support for bundling additional assets within persona folders
### Persona Schema Requirements
The `persona.yaml` file must conform to the following schema:
- **name** (required): Hyphen-delimited lowercase string matching the folder name
- **description** (required): Human-readable description with minimum text
- **toolsets** (optional): Array of toolset configuration objects
- **defaultToolset** (optional): Name of the default toolset (must exist in toolsets array)
### Toolset Schema Requirements
Each toolset object must contain:
- **name** (required): Hyphen-delimited lowercase string
- **toolIds** (required): Array of at least one tool identifier with MCP server prefix (e.g., "git.status", "docker.ps")
## Architecture Design
### Design Principles
1. **Content-First**: Personas are self-contained content bundles that can be easily shared and distributed
2. **Leverage Existing Systems**: Build upon hypertool-mcp's established configuration and toolset management
3. **Progressive Enhancement**: Start with basic YAML support, extend with additional features
4. **Validation-Heavy**: Comprehensive validation at multiple layers to ensure correctness
5. **Seamless Integration**: Work naturally with existing discovery and toolset systems
### Component Architecture
```
Persona Discovery � Persona Loader � Persona Manager
� � �
File System Validator Toolset Manager
Scanning Integration
```
## Schema Definitions
### TypeScript Interfaces
```typescript
// src/persona/types.ts
/**
* Toolset configuration within a persona
*/
export interface PersonaToolset {
/** Toolset name (hyphen-delimited lowercase) */
name: string;
/** Array of tool IDs with MCP server prefix (e.g., "git.status", "docker.ps") */
toolIds: string[];
}
/**
* Main persona configuration schema
*/
export interface PersonaConfig {
/** Persona name (hyphen-delimited lowercase, must match folder name) */
name: string;
/** Human-readable description of the persona */
description: string;
/** Optional array of toolset configurations */
toolsets?: PersonaToolset[];
/** Optional default toolset name (must exist in toolsets array) */
defaultToolset?: string;
/** Schema version for future compatibility */
version?: string;
/** Additional metadata */
metadata?: {
/** Persona author */
author?: string;
/** Categorization tags */
tags?: string[];
/** Creation timestamp */
created?: string;
/** Last modification timestamp */
lastModified?: string;
};
}
/**
* Persona asset information
*/
export interface PersonaAssets {
/** Path to persona.yaml/yml file */
configFile: string;
/** Path to optional mcp.json file */
mcpConfigFile?: string;
/** Array of additional asset file paths */
assetFiles?: string[];
/** Whether persona is in .htp archive format */
isArchived?: boolean;
/** Archive path if isArchived is true */
archivePath?: string;
}
/**
* Complete loaded persona with all associated data
*/
export interface LoadedPersona {
/** Parsed persona configuration */
config: PersonaConfig;
/** Asset file information */
assets: PersonaAssets;
/** Loaded MCP configuration if present */
mcpConfig?: MCPConfig;
/** Validation result */
validation: ValidationResult;
/** Load timestamp */
loadedAt: Date;
/** Source directory or archive path */
sourcePath: string;
}
/**
* Persona discovery result
*/
export interface PersonaDiscoveryResult {
/** Found persona folders/archives */
personas: PersonaReference[];
/** Discovery errors */
errors: string[];
/** Discovery warnings */
warnings: string[];
/** Search locations */
searchPaths: string[];
}
/**
* Reference to a discovered persona
*/
export interface PersonaReference {
/** Persona name from config */
name: string;
/** Full path to persona folder or archive */
path: string;
/** Whether this is an archive (.htp) file */
isArchive: boolean;
/** Brief description if parseable */
description?: string;
/** Whether persona appears valid */
isValid: boolean;
/** Any validation issues found during discovery */
issues?: string[];
}
/**
* Validation result structure
*/
export interface ValidationResult {
/** Overall validation status */
isValid: boolean;
/** Array of validation errors */
errors: PersonaValidationError[];
/** Array of validation warnings */
warnings: PersonaValidationError[];
}
/**
* Detailed validation error information
*/
export interface PersonaValidationError {
/** Type of validation error */
type: 'schema' | 'business' | 'tool-resolution' | 'mcp-config';
/** Specific field that failed validation */
field?: string;
/** Human-readable error message */
message: string;
/** Suggestion for fixing the error */
suggestion?: string;
/** Error severity */
severity: 'error' | 'warning';
}
/**
* Result of persona activation
*/
export interface ActivationResult {
/** Whether activation succeeded */
success: boolean;
/** Activated persona name */
personaName: string;
/** Activated toolset name if any */
activatedToolset?: string;
/** Any errors during activation */
errors?: string[];
/** Any warnings during activation */
warnings?: string[];
}
```
## File System Structure
### Standard Persona Folder
```
my-dev-persona/ # Folder name must match persona.name
persona.yaml # Required: Persona configuration
mcp.json # Optional: MCP server configuration
assets/ # Optional: Additional resources
scripts/ # Custom scripts
documentation/ # Persona-specific docs
templates/ # File templates
README.md # Optional: Persona documentation
```
### Example persona.yaml
```yaml
name: my-dev-persona
description: "Full-stack development persona with Git, Docker, and Node.js tools"
version: "1.0.0"
toolsets:
- name: backend-essentials
toolIds:
- git.status
- git.commit
- docker.ps
- docker.compose
- npm.install
- npm.run
- name: frontend-tools
toolIds:
- npm.run
- webpack.build
- eslint.check
- prettier.format
- name: full-stack
toolIds:
- git.status
- git.commit
- docker.ps
- docker.compose
- npm.install
- npm.run
- webpack.build
- eslint.check
- prettier.format
defaultToolset: backend-essentials
metadata:
author: "John Doe"
tags: ["development", "full-stack", "nodejs"]
created: "2024-01-15T10:00:00Z"
lastModified: "2024-01-20T15:30:00Z"
```
### Archive Format (.htp)
Future enhancement: ZIP archive with `.htp` extension containing the complete persona folder structure.
```
my-dev-persona.htp (ZIP archive)
my-dev-persona/
persona.yaml
mcp.json
assets/
```
## Implementation Components
### Directory Structure
```
src/
persona/ # Persona system implementation
types.ts # TypeScript interfaces and types
loader.ts # Persona loading and parsing logic
manager.ts # Persona lifecycle management
validator.ts # Schema and business logic validation
discovery.ts # Persona folder/archive discovery
cache.ts # Persona caching mechanism
index.ts # Public API exports
config/
personaConfigLoader.ts # Integration with config system
server/tools/persona/ # MCP tools for persona management
list-personas.ts # List available personas
validate-persona.ts # Validate persona structure
activate-persona.ts # Activate a persona
get-active-persona.ts # Get current active persona
deactivate-persona.ts # Deactivate current persona
```
### Core Classes
#### PersonaDiscovery
```typescript
export class PersonaDiscovery {
private standardPaths: string[];
constructor(additionalPaths?: string[]) {
this.standardPaths = [
path.join(getHomeDir(), '.toolprint/hypertool-mcp/personas'),
path.join(process.cwd(), 'personas'),
'./personas',
...additionalPaths || []
];
}
async discoverPersonas(): Promise<PersonaDiscoveryResult>;
async validatePersonaStructure(personaPath: string): Promise<ValidationResult>;
private async scanDirectory(dir: string): Promise<PersonaReference[]>;
private async quickValidate(personaPath: string): Promise<boolean>;
}
```
#### PersonaLoader
```typescript
export class PersonaLoader {
constructor(private validator: PersonaValidator) {}
async loadPersona(personaPath: string): Promise<LoadedPersona>;
async loadPersonaFromArchive(htpPath: string): Promise<LoadedPersona>;
private async parseYamlConfig(filePath: string): Promise<PersonaConfig>;
private async loadMcpConfig(personaPath: string): Promise<MCPConfig | undefined>;
private async catalogAssets(personaPath: string): Promise<string[]>;
}
```
#### PersonaManager
```typescript
export class PersonaManager extends EventEmitter {
constructor(
private discoveryEngine: IToolDiscoveryEngine,
private toolsetManager: ToolsetManager,
private configManager: ConfigManager
) {
super();
}
async activatePersona(personaName: string): Promise<ActivationResult>;
async deactivatePersona(): Promise<void>;
async getActivePersona(): Promise<LoadedPersona | null>;
async listAvailablePersonas(): Promise<PersonaReference[]>;
private async validateToolAvailability(toolIds: string[]): Promise<ValidationResult>;
private async applyMcpConfiguration(mcpConfig: MCPConfig): Promise<void>;
}
```
#### PersonaValidator
```typescript
export class PersonaValidator {
async validatePersonaConfig(config: any): Promise<ValidationResult>;
async validateToolsetReferences(toolsets: PersonaToolset[], availableTools: string[]): Promise<ValidationResult>;
private validateSchemaStructure(config: any): ValidationResult;
private validateBusinessRules(config: PersonaConfig): ValidationResult;
private validateNameFormat(name: string): boolean;
private validateToolIdFormat(toolId: string): boolean;
}
```
## Validation Strategy
### Validation Layers
1. **YAML Structure Validation**
- Valid YAML syntax
- Required fields present
- Correct data types
2. **Schema Validation**
- Field format validation (hyphen-delimited names)
- Array requirements (min 1 toolId)
- String length requirements
3. **Business Logic Validation**
- Folder name matches persona name
- defaultToolset exists in toolsets array
- No duplicate toolset names
- No duplicate toolIds within a toolset
4. **Tool Resolution Validation**
- All toolIds reference existing tools
- Server prefixes are valid
- Tools are available in current discovery
5. **MCP Configuration Validation**
- Valid MCP config format
- Server definitions are correct
- No conflicts with existing configurations
### Validation Error Examples
```typescript
// Schema error
{
type: 'schema',
field: 'name',
message: 'Persona name must be hyphen-delimited lowercase',
suggestion: 'Use "my-persona" instead of "My Persona"',
severity: 'error'
}
// Business logic error
{
type: 'business',
field: 'defaultToolset',
message: 'Default toolset "frontend" not found in toolsets array',
suggestion: 'Add "frontend" to toolsets or choose an existing toolset',
severity: 'error'
}
// Tool resolution warning
{
type: 'tool-resolution',
field: 'toolsets[0].toolIds[2]',
message: 'Tool "docker.build" not currently available',
suggestion: 'Ensure Docker MCP server is configured and connected',
severity: 'warning'
}
```
## Integration Points
### 1. Configuration System Integration
```typescript
// Extend MCPConfigLoader to support persona configs
class PersonaConfigLoader extends MCPConfigLoader {
async loadPersonaMcpConfig(personaPath: string): Promise<MCPConfig | null>;
async mergePersonaConfig(baseConfig: MCPConfig, personaConfig: MCPConfig): Promise<MCPConfig>;
}
```
### 2. Toolset System Integration
```typescript
// Extend ToolsetManager for persona support
interface PersonaAwareToolsetManager extends ToolsetManager {
loadPersonaToolsets(persona: LoadedPersona): Promise<void>;
activatePersonaDefaultToolset(persona: LoadedPersona): Promise<void>;
getPersonaContext(): PersonaContext | null;
}
```
### 3. Discovery Engine Integration
```typescript
// Hook into discovery engine for persona MCP configs
interface PersonaAwareDiscoveryEngine extends IToolDiscoveryEngine {
refreshWithPersonaConfig(mcpConfig: MCPConfig): Promise<void>;
getPersonaTools(): Map<string, ToolDefinition>;
}
```
### 4. Event System Integration
```typescript
// Persona-related events
export enum PersonaEvents {
PERSONA_ACTIVATED = 'persona:activated',
PERSONA_DEACTIVATED = 'persona:deactivated',
PERSONA_DISCOVERED = 'persona:discovered',
PERSONA_VALIDATION_FAILED = 'persona:validation:failed',
PERSONA_TOOLSET_CHANGED = 'persona:toolset:changed'
}
```
## API Surface
### MCP Tools
```typescript
// List available personas
{
name: "list-personas",
description: "List all available personas",
inputSchema: {
type: "object",
properties: {
includeInvalid: { type: "boolean", description: "Include invalid personas" }
}
}
}
// Validate persona
{
name: "validate-persona",
description: "Validate a persona's structure and configuration",
inputSchema: {
type: "object",
properties: {
personaPath: { type: "string", description: "Path to persona folder" }
},
required: ["personaPath"]
}
}
// Activate persona
{
name: "activate-persona",
description: "Activate a specific persona",
inputSchema: {
type: "object",
properties: {
personaName: { type: "string", description: "Name of persona to activate" },
toolsetName: { type: "string", description: "Specific toolset to activate" }
},
required: ["personaName"]
}
}
// Get active persona
{
name: "get-active-persona",
description: "Get the currently active persona",
inputSchema: {
type: "object",
properties: {}
}
}
// Deactivate persona
{
name: "deactivate-persona",
description: "Deactivate the current persona",
inputSchema: {
type: "object",
properties: {}
}
}
```
### CLI Commands
```bash
# List personas
hypertool persona list [--include-invalid]
# Validate persona
hypertool persona validate <path>
# Activate persona
hypertool persona activate <name> [--toolset <toolset-name>]
# Show active persona
hypertool persona status
# Deactivate persona
hypertool persona deactivate
# Export persona (future)
hypertool persona export <name> --output <path.htp>
# Import persona (future)
hypertool persona import <path.htp>
```
## Error Handling
### Error Categories
1. **Discovery Errors**
- Invalid directory permissions
- Corrupted YAML files
- Missing required files
2. **Validation Errors**
- Schema violations
- Business rule violations
- Tool resolution failures
3. **Activation Errors**
- Persona not found
- Toolset activation failures
- MCP configuration conflicts
4. **Runtime Errors**
- File system errors
- Network errors (when loading remote tools)
- Memory/resource constraints
### Error Response Format
```typescript
export interface PersonaError extends Error {
code: PersonaErrorCode;
details?: Record<string, any>;
suggestions?: string[];
recoverable: boolean;
}
export enum PersonaErrorCode {
PERSONA_NOT_FOUND = 'PERSONA_NOT_FOUND',
INVALID_SCHEMA = 'INVALID_SCHEMA',
VALIDATION_FAILED = 'VALIDATION_FAILED',
ACTIVATION_FAILED = 'ACTIVATION_FAILED',
TOOLSET_NOT_FOUND = 'TOOLSET_NOT_FOUND',
TOOL_RESOLUTION_FAILED = 'TOOL_RESOLUTION_FAILED',
MCP_CONFIG_CONFLICT = 'MCP_CONFIG_CONFLICT',
FILE_SYSTEM_ERROR = 'FILE_SYSTEM_ERROR'
}
```
## Future Enhancements
### Phase 1: Core Implementation (Current)
- Basic persona loading and validation
- Integration with existing systems
- MCP tools for management
### Phase 2: Archive Support
- `.htp` ZIP archive creation and extraction
- Compression optimization
- Archive validation
### Phase 3: Advanced Features
- Remote persona repositories
- Persona versioning and updates
- Dependency management between personas
- Persona inheritance/composition
### Phase 4: Enterprise Features
- Digital signing for trusted personas
- Access control and permissions
- Audit logging for persona changes
- Persona marketplace/registry
### Phase 5: Developer Experience
- Visual persona editor
- Persona templates and wizards
- Auto-generation from existing configurations
- Migration tools from other formats
## Conclusion
The persona content loading system provides a powerful, extensible mechanism for managing tool configurations in hypertool-mcp. By leveraging the existing architecture and following established patterns, this system integrates seamlessly while adding significant value for users who need to switch between different development contexts.
The design prioritizes validation, clear error messages, and progressive enhancement, ensuring a robust foundation that can grow with future requirements while maintaining backward compatibility.