Skip to main content
Glama

init_portfolio

Initialize a GitHub repository for organizing and storing DollhouseMCP AI persona elements with proper directory structure and documentation.

Instructions

Initialize a new GitHub portfolio repository for storing your DollhouseMCP elements. Creates the repository structure with proper directories and README.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
repository_nameNoName for the portfolio repository. Defaults to 'dollhouse-portfolio' if not specified.
privateNoWhether to create a private repository. Defaults to false (public).
descriptionNoRepository description. Defaults to 'My DollhouseMCP element portfolio'.

Implementation Reference

  • MCP tool registration for 'init_portfolio' including name, description, input schema, and handler function that maps args to server.initPortfolio call.
    tool: { name: "init_portfolio", description: "Initialize a new GitHub portfolio repository for storing your DollhouseMCP elements. Creates the repository structure with proper directories and README.", inputSchema: { type: "object", properties: { repository_name: { type: "string", description: "Name for the portfolio repository. Defaults to 'dollhouse-portfolio' if not specified.", }, private: { type: "boolean", description: "Whether to create a private repository. Defaults to false (public).", }, description: { type: "string", description: "Repository description. Defaults to 'My DollhouseMCP element portfolio'.", }, }, }, }, handler: (args: InitPortfolioArgs) => server.initPortfolio({ repositoryName: args?.repository_name, private: args?.private, description: args?.description }) },
  • TypeScript interface defining input arguments for the init_portfolio tool.
    interface InitPortfolioArgs { repository_name?: string; private?: boolean; description?: string; }
  • Core implementation logic for creating the GitHub portfolio repository, called by server.initPortfolio. Handles consent, repo creation via GitHub API, and structure initialization.
    async createPortfolio(username: string, consent: boolean | undefined): Promise<string> { // MEDIUM FIX: Normalize username to prevent Unicode attacks (DMCP-SEC-004) const normalizedUsername = UnicodeValidator.normalize(username).normalizedContent; // CRITICAL: Validate consent is explicitly provided if (consent === undefined) { throw new Error('Consent is required for portfolio creation'); } if (!consent) { logger.info(`User declined portfolio creation for ${username}`); throw new Error('User declined portfolio creation'); } // Log consent for audit trail logger.info(`User consented to portfolio creation for ${normalizedUsername}`); // LOW FIX: Add security audit logging (DMCP-SEC-006) SecurityMonitor.logSecurityEvent({ type: 'PORTFOLIO_INITIALIZATION', severity: 'LOW', source: 'PortfolioRepoManager.createPortfolio', details: `User ${normalizedUsername} consented to portfolio creation`, metadata: { username: normalizedUsername } }); // Check if portfolio already exists const existingRepo = await this.githubRequest( `/repos/${normalizedUsername}/${this.repositoryName}` ); if (existingRepo && existingRepo.html_url) { logger.info(`Portfolio already exists for ${normalizedUsername}`); return existingRepo.html_url; } // Create the portfolio repository try { const repo = await this.githubRequest( '/user/repos', 'POST', { name: this.repositoryName, description: PortfolioRepoManager.DEFAULT_DESCRIPTION, private: false, auto_init: true } ); // Initialize portfolio structure await this.generatePortfolioStructure(normalizedUsername); return repo.html_url; } catch (error: any) { // Handle race condition: if repository was created between our check and creation attempt if (error.message && error.message.includes('name already exists')) { logger.info(`Portfolio repository already exists for ${normalizedUsername} (race condition handled)`); // Re-check for the existing repository and return its URL try { const existingRepo = await this.githubRequest( `/repos/${normalizedUsername}/${this.repositoryName}` ); if (existingRepo && existingRepo.html_url) { return existingRepo.html_url; } } catch (recheckError) { ErrorHandler.logError('PortfolioRepoManager.recheckExistingRepo', recheckError, { username: normalizedUsername }); } // If we can't get the existing repo, throw a more specific error throw new Error(`Portfolio repository already exists for ${normalizedUsername}. Please check your GitHub account.`); } ErrorHandler.logError('PortfolioRepoManager.createPortfolioRepo', error, { username: normalizedUsername }); throw ErrorHandler.wrapError(error, `Failed to create portfolio repository for ${normalizedUsername}. ${error.message || 'Unknown error occurred.'}`, ErrorCategory.NETWORK_ERROR); } }
  • Registration of all portfolio tools (including init_portfolio) into the ToolRegistry during server setup.
    // Portfolio tools (including sync_portfolio with new safety features) this.toolRegistry.registerMany(getPortfolioTools(instance));
  • IToolHandler interface defining the server.initPortfolio method signature used by the tool handler.
    initPortfolio(options: {repositoryName?: string; private?: boolean; description?: string}): Promise<any>; portfolioConfig(options: {autoSync?: boolean; defaultVisibility?: string; autoSubmit?: boolean; repositoryName?: string}): Promise<any>;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/DollhouseMCP/DollhouseMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server