@mickdarling/dollhousemcp
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.
71 lines • 10.8 kB
JavaScript
/**
* Get persona details from marketplace
*/
import { ContentValidator } from '../security/contentValidator.js';
import { SecureYamlParser } from '../security/secureYamlParser.js';
import { SecurityError } from '../errors/SecurityError.js';
export class PersonaDetails {
githubClient;
baseUrl = 'https://api.github.com/repos/DollhouseMCP/personas/contents/personas';
constructor(githubClient) {
this.githubClient = githubClient;
}
/**
* Get detailed information about a marketplace persona
*/
async getMarketplacePersona(path) {
const url = `${this.baseUrl}/${path}`;
const data = await this.githubClient.fetchFromGitHub(url);
if (data.type !== 'file') {
throw new Error('Path does not point to a file');
}
// Decode Base64 content
const content = Buffer.from(data.content, 'base64').toString('utf-8');
// Sanitize content for display (this is view-only, not installation)
const sanitizedContent = ContentValidator.sanitizePersonaContent(content);
// Use secure YAML parser
let parsed;
try {
parsed = SecureYamlParser.safeMatter(sanitizedContent);
}
catch (error) {
if (error instanceof SecurityError) {
throw new Error(`Security warning: This persona contains potentially malicious content - ${error.message}`);
}
throw error;
}
const metadata = parsed.data;
// Additional validation for display
const metadataValidation = ContentValidator.validateMetadata(metadata);
if (!metadataValidation.isValid && metadataValidation.severity === 'critical') {
throw new Error(`Security warning: This persona contains potentially malicious content`);
}
return {
metadata,
content: parsed.content
};
}
/**
* Format persona details for display
*/
formatPersonaDetails(metadata, content, path, personaIndicator = '') {
const textParts = [
`${personaIndicator}🎭 **Marketplace Persona: ${metadata.name}**\n\n`,
`**📋 Details:**\n`,
` 🆔 ID: ${metadata.unique_id || 'Not specified'}\n`,
` 👤 Author: ${metadata.author || 'Unknown'}\n`,
` 📁 Category: ${metadata.category || 'General'}\n`,
` 🔖 Price: ${metadata.price || 'Free'}\n`,
` 📊 Version: ${metadata.version || '1.0'}\n`,
` 🔞 Age Rating: ${metadata.age_rating || 'All'}\n`,
` ${metadata.ai_generated ? '🤖 AI Generated' : '👤 Human Created'}\n\n`,
`**📝 Description:**\n${metadata.description}\n\n`
];
if (metadata.triggers && metadata.triggers.length > 0) {
textParts.push(`**🔗 Triggers:** ${metadata.triggers.join(', ')}\n\n`);
}
textParts.push(`**📥 Installation:**\n`, `Use: \`install_persona "${path}"\`\n\n`, `**📄 Full Content:**\n\`\`\`\n${content}\n\`\`\``);
return textParts.join('');
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGVyc29uYURldGFpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbWFya2V0cGxhY2UvUGVyc29uYURldGFpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFLSCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFM0QsTUFBTSxPQUFPLGNBQWM7SUFDakIsWUFBWSxDQUFlO0lBQzNCLE9BQU8sR0FBRyxzRUFBc0UsQ0FBQztJQUV6RixZQUFZLFlBQTBCO1FBQ3BDLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO0lBQ25DLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxJQUFZO1FBQ3RDLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUV0QyxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRTFELElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFDbkQsQ0FBQztRQUVELHdCQUF3QjtRQUN4QixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXRFLHFFQUFxRTtRQUNyRSxNQUFNLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTFFLHlCQUF5QjtRQUN6QixJQUFJLE1BQU0sQ0FBQztRQUNYLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxZQUFZLGFBQWEsRUFBRSxDQUFDO2dCQUNuQyxNQUFNLElBQUksS0FBSyxDQUFDLDJFQUEyRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUM5RyxDQUFDO1lBQ0QsTUFBTSxLQUFLLENBQUM7UUFDZCxDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQXVCLENBQUM7UUFFaEQsb0NBQW9DO1FBQ3BDLE1BQU0sa0JBQWtCLEdBQUcsZ0JBQWdCLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sSUFBSSxrQkFBa0IsQ0FBQyxRQUFRLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDOUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx1RUFBdUUsQ0FBQyxDQUFDO1FBQzNGLENBQUM7UUFFRCxPQUFPO1lBQ0wsUUFBUTtZQUNSLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztTQUN4QixDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0gsb0JBQW9CLENBQUMsUUFBeUIsRUFBRSxPQUFlLEVBQUUsSUFBWSxFQUFFLG1CQUEyQixFQUFFO1FBQzFHLE1BQU0sU0FBUyxHQUFHO1lBQ2hCLEdBQUcsZ0JBQWdCLDZCQUE2QixRQUFRLENBQUMsSUFBSSxRQUFRO1lBQ3JFLG1CQUFtQjtZQUNuQixhQUFhLFFBQVEsQ0FBQyxTQUFTLElBQUksZUFBZSxJQUFJO1lBQ3RELGlCQUFpQixRQUFRLENBQUMsTUFBTSxJQUFJLFNBQVMsSUFBSTtZQUNqRCxtQkFBbUIsUUFBUSxDQUFDLFFBQVEsSUFBSSxTQUFTLElBQUk7WUFDckQsZ0JBQWdCLFFBQVEsQ0FBQyxLQUFLLElBQUksTUFBTSxJQUFJO1lBQzVDLGtCQUFrQixRQUFRLENBQUMsT0FBTyxJQUFJLEtBQUssSUFBSTtZQUMvQyxxQkFBcUIsUUFBUSxDQUFDLFVBQVUsSUFBSSxLQUFLLElBQUk7WUFDckQsTUFBTSxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLE1BQU07WUFDMUUsd0JBQXdCLFFBQVEsQ0FBQyxXQUFXLE1BQU07U0FDbkQsQ0FBQztRQUVGLElBQUksUUFBUSxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN0RCxTQUFTLENBQUMsSUFBSSxDQUFDLG9CQUFvQixRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDekUsQ0FBQztRQUVELFNBQVMsQ0FBQyxJQUFJLENBQ1osd0JBQXdCLEVBQ3hCLDJCQUEyQixJQUFJLFNBQVMsRUFDeEMsaUNBQWlDLE9BQU8sVUFBVSxDQUNuRCxDQUFDO1FBRUYsT0FBTyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzVCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2V0IHBlcnNvbmEgZGV0YWlscyBmcm9tIG1hcmtldHBsYWNlXG4gKi9cblxuaW1wb3J0IG1hdHRlciBmcm9tICdncmF5LW1hdHRlcic7XG5pbXBvcnQgeyBHaXRIdWJDbGllbnQgfSBmcm9tICcuL0dpdEh1YkNsaWVudC5qcyc7XG5pbXBvcnQgeyBQZXJzb25hTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9wZXJzb25hLmpzJztcbmltcG9ydCB7IENvbnRlbnRWYWxpZGF0b3IgfSBmcm9tICcuLi9zZWN1cml0eS9jb250ZW50VmFsaWRhdG9yLmpzJztcbmltcG9ydCB7IFNlY3VyZVlhbWxQYXJzZXIgfSBmcm9tICcuLi9zZWN1cml0eS9zZWN1cmVZYW1sUGFyc2VyLmpzJztcbmltcG9ydCB7IFNlY3VyaXR5RXJyb3IgfSBmcm9tICcuLi9lcnJvcnMvU2VjdXJpdHlFcnJvci5qcyc7XG5cbmV4cG9ydCBjbGFzcyBQZXJzb25hRGV0YWlscyB7XG4gIHByaXZhdGUgZ2l0aHViQ2xpZW50OiBHaXRIdWJDbGllbnQ7XG4gIHByaXZhdGUgYmFzZVVybCA9ICdodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zL0RvbGxob3VzZU1DUC9wZXJzb25hcy9jb250ZW50cy9wZXJzb25hcyc7XG4gIFxuICBjb25zdHJ1Y3RvcihnaXRodWJDbGllbnQ6IEdpdEh1YkNsaWVudCkge1xuICAgIHRoaXMuZ2l0aHViQ2xpZW50ID0gZ2l0aHViQ2xpZW50O1xuICB9XG4gIFxuICAvKipcbiAgICogR2V0IGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IGEgbWFya2V0cGxhY2UgcGVyc29uYVxuICAgKi9cbiAgYXN5bmMgZ2V0TWFya2V0cGxhY2VQZXJzb25hKHBhdGg6IHN0cmluZyk6IFByb21pc2U8eyBtZXRhZGF0YTogUGVyc29uYU1ldGFkYXRhOyBjb250ZW50OiBzdHJpbmcgfT4ge1xuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuYmFzZVVybH0vJHtwYXRofWA7XG4gICAgXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuZ2l0aHViQ2xpZW50LmZldGNoRnJvbUdpdEh1Yih1cmwpO1xuICAgIFxuICAgIGlmIChkYXRhLnR5cGUgIT09ICdmaWxlJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXRoIGRvZXMgbm90IHBvaW50IHRvIGEgZmlsZScpO1xuICAgIH1cbiAgICBcbiAgICAvLyBEZWNvZGUgQmFzZTY0IGNvbnRlbnRcbiAgICBjb25zdCBjb250ZW50ID0gQnVmZmVyLmZyb20oZGF0YS5jb250ZW50LCAnYmFzZTY0JykudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgXG4gICAgLy8gU2FuaXRpemUgY29udGVudCBmb3IgZGlzcGxheSAodGhpcyBpcyB2aWV3LW9ubHksIG5vdCBpbnN0YWxsYXRpb24pXG4gICAgY29uc3Qgc2FuaXRpemVkQ29udGVudCA9IENvbnRlbnRWYWxpZGF0b3Iuc2FuaXRpemVQZXJzb25hQ29udGVudChjb250ZW50KTtcbiAgICBcbiAgICAvLyBVc2Ugc2VjdXJlIFlBTUwgcGFyc2VyXG4gICAgbGV0IHBhcnNlZDtcbiAgICB0cnkge1xuICAgICAgcGFyc2VkID0gU2VjdXJlWWFtbFBhcnNlci5zYWZlTWF0dGVyKHNhbml0aXplZENvbnRlbnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBTZWN1cml0eUVycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgU2VjdXJpdHkgd2FybmluZzogVGhpcyBwZXJzb25hIGNvbnRhaW5zIHBvdGVudGlhbGx5IG1hbGljaW91cyBjb250ZW50IC0gJHtlcnJvci5tZXNzYWdlfWApO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIFxuICAgIGNvbnN0IG1ldGFkYXRhID0gcGFyc2VkLmRhdGEgYXMgUGVyc29uYU1ldGFkYXRhO1xuICAgIFxuICAgIC8vIEFkZGl0aW9uYWwgdmFsaWRhdGlvbiBmb3IgZGlzcGxheVxuICAgIGNvbnN0IG1ldGFkYXRhVmFsaWRhdGlvbiA9IENvbnRlbnRWYWxpZGF0b3IudmFsaWRhdGVNZXRhZGF0YShtZXRhZGF0YSk7XG4gICAgaWYgKCFtZXRhZGF0YVZhbGlkYXRpb24uaXNWYWxpZCAmJiBtZXRhZGF0YVZhbGlkYXRpb24uc2V2ZXJpdHkgPT09ICdjcml0aWNhbCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU2VjdXJpdHkgd2FybmluZzogVGhpcyBwZXJzb25hIGNvbnRhaW5zIHBvdGVudGlhbGx5IG1hbGljaW91cyBjb250ZW50YCk7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiB7XG4gICAgICBtZXRhZGF0YSxcbiAgICAgIGNvbnRlbnQ6IHBhcnNlZC5jb250ZW50XG4gICAgfTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEZvcm1hdCBwZXJzb25hIGRldGFpbHMgZm9yIGRpc3BsYXlcbiAgICovXG4gIGZvcm1hdFBlcnNvbmFEZXRhaWxzKG1ldGFkYXRhOiBQZXJzb25hTWV0YWRhdGEsIGNvbnRlbnQ6IHN0cmluZywgcGF0aDogc3RyaW5nLCBwZXJzb25hSW5kaWNhdG9yOiBzdHJpbmcgPSAnJyk6IHN0cmluZyB7XG4gICAgY29uc3QgdGV4dFBhcnRzID0gW1xuICAgICAgYCR7cGVyc29uYUluZGljYXRvcn3wn46tICoqTWFya2V0cGxhY2UgUGVyc29uYTogJHttZXRhZGF0YS5uYW1lfSoqXFxuXFxuYCxcbiAgICAgIGAqKvCfk4sgRGV0YWlsczoqKlxcbmAsXG4gICAgICBgICAg8J+GlCBJRDogJHttZXRhZGF0YS51bmlxdWVfaWQgfHwgJ05vdCBzcGVjaWZpZWQnfVxcbmAsXG4gICAgICBgICAg8J+RpCBBdXRob3I6ICR7bWV0YWRhdGEuYXV0aG9yIHx8ICdVbmtub3duJ31cXG5gLFxuICAgICAgYCAgIPCfk4EgQ2F0ZWdvcnk6ICR7bWV0YWRhdGEuY2F0ZWdvcnkgfHwgJ0dlbmVyYWwnfVxcbmAsXG4gICAgICBgICAg8J+UliBQcmljZTogJHttZXRhZGF0YS5wcmljZSB8fCAnRnJlZSd9XFxuYCxcbiAgICAgIGAgICDwn5OKIFZlcnNpb246ICR7bWV0YWRhdGEudmVyc2lvbiB8fCAnMS4wJ31cXG5gLFxuICAgICAgYCAgIPCflJ4gQWdlIFJhdGluZzogJHttZXRhZGF0YS5hZ2VfcmF0aW5nIHx8ICdBbGwnfVxcbmAsXG4gICAgICBgICAgJHttZXRhZGF0YS5haV9nZW5lcmF0ZWQgPyAn8J+kliBBSSBHZW5lcmF0ZWQnIDogJ/CfkaQgSHVtYW4gQ3JlYXRlZCd9XFxuXFxuYCxcbiAgICAgIGAqKvCfk50gRGVzY3JpcHRpb246KipcXG4ke21ldGFkYXRhLmRlc2NyaXB0aW9ufVxcblxcbmBcbiAgICBdO1xuICAgIFxuICAgIGlmIChtZXRhZGF0YS50cmlnZ2VycyAmJiBtZXRhZGF0YS50cmlnZ2Vycy5sZW5ndGggPiAwKSB7XG4gICAgICB0ZXh0UGFydHMucHVzaChgKirwn5SXIFRyaWdnZXJzOioqICR7bWV0YWRhdGEudHJpZ2dlcnMuam9pbignLCAnKX1cXG5cXG5gKTtcbiAgICB9XG4gICAgXG4gICAgdGV4dFBhcnRzLnB1c2goXG4gICAgICBgKirwn5OlIEluc3RhbGxhdGlvbjoqKlxcbmAsXG4gICAgICBgVXNlOiBcXGBpbnN0YWxsX3BlcnNvbmEgXCIke3BhdGh9XCJcXGBcXG5cXG5gLFxuICAgICAgYCoq8J+ThCBGdWxsIENvbnRlbnQ6KipcXG5cXGBcXGBcXGBcXG4ke2NvbnRlbnR9XFxuXFxgXFxgXFxgYFxuICAgICk7XG4gICAgXG4gICAgcmV0dXJuIHRleHRQYXJ0cy5qb2luKCcnKTtcbiAgfVxufSJdfQ==