Skip to main content
Glama

create_blueprint

Generate tech stack blueprints for projects by specifying project type, scale, and priorities to receive tailored technology recommendations.

Instructions

Creates a new tech stack blueprint for a project. Requires API key with 'blueprint:write' scope.

The blueprint generation is asynchronous. By default, this tool waits for completion and returns the full blueprint. Set waitForCompletion=false to get the job ID immediately for manual polling.

Example usage:

  • Create a SaaS MVP: projectType="saas", scale="mvp", priorities=["time-to-market", "cost-efficiency"]

  • Create an enterprise API: projectType="api", scale="enterprise", priorities=["security", "scalability"]

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectNameNoProject name (optional)
projectTypeYesType of project
scaleYesProject scale
projectDescriptionNoBrief description (optional)
prioritiesNoTop 3 priorities (optional)
constraintsNoTechnology constraint IDs (optional)
waitForCompletionNoWait for completion (default: true)

Implementation Reference

  • Main handler function that implements the create_blueprint tool logic: builds API request, creates blueprint job, handles polling or immediate job info, fetches and formats the blueprint result, with comprehensive error handling.
    export async function executeCreateBlueprint(
    	input: CreateBlueprintInput
    ): Promise<{ text: string; isError?: boolean }> {
    	const {
    		projectName,
    		projectType,
    		scale,
    		projectDescription,
    		priorities,
    		constraints,
    		waitForCompletion = true
    	} = input;
    
    	debug('Creating blueprint', { projectType, scale, waitForCompletion });
    
    	try {
    		// Build request body
    		const requestBody: CreateBlueprintRequest = {
    			projectName,
    			projectContext: {
    				projectName,
    				projectType,
    				projectDescription,
    				scale,
    				priorities: priorities as CreateBlueprintRequest['projectContext']['priorities'],
    				constraintIds: constraints
    			},
    			source: 'mcp',
    			mcpToolName: 'create_blueprint'
    		};
    
    		// Create the blueprint job
    		const createResponse = await createBlueprintRequest(requestBody);
    
    		// If already completed (cached result), fetch and return
    		if (createResponse.status === 'completed' && createResponse.resultRef) {
    			const blueprint = await getBlueprintRequest<BlueprintApiResponse>(createResponse.resultRef);
    			const text = formatBlueprint(blueprint);
    			return {
    				text: `## Blueprint Created (Cached)\n\n${text}\n\n---\n*Source: MCP Server*`
    			};
    		}
    
    		// If not waiting, return job info
    		if (!waitForCompletion) {
    			return {
    				text: `## Blueprint Generation Started
    
    **Job ID**: ${createResponse.jobId}
    **Project ID**: ${createResponse.projectId}
    **Status**: ${createResponse.status}
    **Progress**: ${createResponse.progress}%
    
    Poll the job status at: ${createResponse._links.job}
    Once complete, fetch the blueprint at: ${createResponse._links.blueprint || 'TBD'}
    
    ---
    *Source: MCP Server*`
    			};
    		}
    
    		// Poll until completion
    		debug('Polling job until completion', { jobId: createResponse.jobId });
    		const finalStatus = await pollJobUntilComplete(createResponse.jobId);
    
    		if (!finalStatus.resultRef) {
    			throw new McpError(ErrorCode.API_ERROR, 'Job completed but no blueprint ID returned');
    		}
    
    		// Fetch the completed blueprint
    		const blueprint = await getBlueprintRequest<BlueprintApiResponse>(finalStatus.resultRef);
    		const text = formatBlueprint(blueprint);
    
    		return {
    			text: `## Blueprint Created Successfully
    
    ${text}
    
    ---
    **Job ID**: ${createResponse.jobId}
    **Project ID**: ${createResponse.projectId}
    *Source: MCP Server*`
    		};
    	} catch (err) {
    		if (err instanceof McpError) {
    			// Add helpful suggestions for common errors
    			if (err.code === ErrorCode.CONFIG_ERROR) {
    				err.suggestions = [
    					'Ensure STACKSFINDER_API_KEY is set with a valid Pro or Team API key.',
    					'Get your API key from https://stacksfinder.com/settings/api'
    				];
    			} else if (err.code === ErrorCode.UNAUTHORIZED) {
    				err.suggestions = [
    					"Your API key may be invalid or missing the 'blueprint:write' scope.",
    					'Generate a new API key with the correct permissions at https://stacksfinder.com/settings/api'
    				];
    			} else if (err.code === ErrorCode.RATE_LIMITED) {
    				err.suggestions = [
    					'You have exceeded your monthly blueprint quota.',
    					'Upgrade your plan at https://stacksfinder.com/pricing'
    				];
    			}
    			return { text: err.toResponseText(), isError: true };
    		}
    
    		const error = new McpError(
    			ErrorCode.API_ERROR,
    			err instanceof Error ? err.message : 'Failed to create blueprint'
    		);
    		return { text: error.toResponseText(), isError: true };
    	}
    }
  • Zod input schema for validating parameters to the create_blueprint tool.
    export const CreateBlueprintInputSchema = z.object({
    	projectName: z.string().min(1).max(100).optional().describe('Project name (optional)'),
    	projectType: z
    		.enum(PROJECT_TYPES)
    		.describe('Type of project (e.g., web-app, saas, api)'),
    	scale: z.enum(SCALES).describe('Project scale (mvp, startup, growth, enterprise)'),
    	projectDescription: z
    		.string()
    		.max(2000)
    		.optional()
    		.describe('Brief project description (optional)'),
    	priorities: z
    		.array(z.enum(PRIORITIES))
    		.max(3)
    		.optional()
    		.describe('Top 3 priorities (optional)'),
    	constraints: z
    		.array(z.string())
    		.max(20)
    		.optional()
    		.describe('Technology constraint IDs (optional)'),
    	waitForCompletion: z
    		.boolean()
    		.optional()
    		.default(true)
    		.describe('Wait for blueprint generation to complete (default: true)')
    });
  • src/server.ts:244-300 (registration)
    MCP server registration of the create_blueprint tool, including title, description, Zod input schema mirroring the exported schema, annotations, and wrapper handler that delegates to executeCreateBlueprint.
    // Register create_blueprint tool (API-based, requires API key with blueprint:write)
    server.registerTool(
    	createBlueprintToolDefinition.name,
    	{
    		title: 'Create Blueprint',
    		description: createBlueprintToolDefinition.description,
    		inputSchema: {
    			projectName: z.string().max(100).optional().describe('Project name (optional)'),
    			projectType: z
    				.enum([
    					'web-app',
    					'mobile-app',
    					'api',
    					'desktop',
    					'cli',
    					'library',
    					'e-commerce',
    					'saas',
    					'marketplace'
    				])
    				.describe('Type of project'),
    			scale: z.enum(['mvp', 'startup', 'growth', 'enterprise']).describe('Project scale'),
    			projectDescription: z.string().max(2000).optional().describe('Brief description (optional)'),
    			priorities: z
    				.array(
    					z.enum([
    						'time-to-market',
    						'scalability',
    						'developer-experience',
    						'cost-efficiency',
    						'performance',
    						'security',
    						'maintainability'
    					])
    				)
    				.max(3)
    				.optional()
    				.describe('Top 3 priorities (optional)'),
    			constraints: z.array(z.string()).max(20).optional().describe('Technology constraint IDs (optional)'),
    			waitForCompletion: z.boolean().optional().describe('Wait for completion (default: true)')
    		},
    		annotations: {
    			readOnlyHint: false,
    			destructiveHint: false,
    			openWorldHint: false
    		}
    	},
    	async (args) => {
    		debug('create_blueprint called', args);
    		const input = CreateBlueprintInputSchema.parse(args);
    		const { text, isError } = await executeCreateBlueprint(input);
    		return {
    			content: [{ type: 'text', text }],
    			isError
    		};
    	}
    );
  • Tool definition object used for registration, containing name, description, and JSON schema for the create_blueprint tool.
    export const createBlueprintToolDefinition = {
    	name: 'create_blueprint',
    	description: `Creates a new tech stack blueprint for a project. Requires API key with 'blueprint:write' scope.
    
    The blueprint generation is asynchronous. By default, this tool waits for completion and returns the full blueprint.
    Set waitForCompletion=false to get the job ID immediately for manual polling.
    
    Example usage:
    - Create a SaaS MVP: projectType="saas", scale="mvp", priorities=["time-to-market", "cost-efficiency"]
    - Create an enterprise API: projectType="api", scale="enterprise", priorities=["security", "scalability"]`,
    	inputSchema: {
    		type: 'object' as const,
    		properties: {
    			projectName: {
    				type: 'string',
    				description: 'Project name (optional)',
    				maxLength: 100
    			},
    			projectType: {
    				type: 'string',
    				enum: PROJECT_TYPES,
    				description: 'Type of project'
    			},
    			scale: {
    				type: 'string',
    				enum: SCALES,
    				description: 'Project scale'
    			},
    			projectDescription: {
    				type: 'string',
    				description: 'Brief project description (optional)',
    				maxLength: 2000
    			},
    			priorities: {
    				type: 'array',
    				items: { type: 'string', enum: PRIORITIES },
    				maxItems: 3,
    				description: 'Top 3 priorities (optional)'
    			},
    			constraints: {
    				type: 'array',
    				items: { type: 'string' },
    				maxItems: 20,
    				description: 'Technology constraint IDs (optional)'
    			},
    			waitForCompletion: {
    				type: 'boolean',
    				description: 'Wait for blueprint generation to complete (default: true)',
    				default: true
    			}
    		},
    		required: ['projectType', 'scale']
    	}
    };
  • Helper function to poll the blueprint job status until completion or failure, used by the handler.
    async function pollJobUntilComplete(
    	jobId: string,
    	maxAttempts = 30,
    	intervalMs = 2000
    ): Promise<JobStatusResponse> {
    	for (let attempt = 0; attempt < maxAttempts; attempt++) {
    		const status = await getJobStatusRequest(jobId);
    
    		if (status.status === 'completed') {
    			return status;
    		}
    
    		if (status.status === 'failed' || status.status === 'cancelled') {
    			throw new McpError(
    				ErrorCode.API_ERROR,
    				status.errorMessage || `Job ${status.status}: ${status.errorCode || 'Unknown error'}`
    			);
    		}
    
    		// Wait before next poll
    		await new Promise((resolve) => setTimeout(resolve, intervalMs));
    	}
    
    	throw new McpError(
    		ErrorCode.TIMEOUT,
    		`Blueprint generation timed out after ${(maxAttempts * intervalMs) / 1000} seconds`,
    		['The job is still running. Use get_blueprint with the job resultRef to check later.']
    	);
    }

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/hoklims/stacksfinder-mcp'

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