scaffold_consumer
Generate consumer code from producer schemas to create TypeScript functions, React hooks, or Zustand actions that correctly call MCP tools, preventing runtime errors by validating contracts during development.
Instructions
Generate consumer code from a producer schema. Creates TypeScript functions, React hooks, or Zustand actions that correctly call MCP tools.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| producerDir | Yes | Path to MCP server source directory | |
| toolName | Yes | Name of the tool to scaffold consumer for | |
| target | No | Output target format | |
| includeErrorHandling | No | Include try/catch error handling | |
| includeTypes | No | Include TypeScript type definitions |
Implementation Reference
- src/index.ts:73-79 (schema)Zod schema defining the input parameters for the scaffold_consumer tool, used for validation.const ScaffoldConsumerInput = z.object({ producerDir: z.string().describe('Path to MCP server source directory'), toolName: z.string().describe('Name of the tool to scaffold consumer for'), target: z.enum(['typescript', 'javascript', 'react-hook', 'zustand-action']).optional().describe('Output target format (default: typescript)'), includeErrorHandling: z.boolean().optional().describe('Include try/catch error handling (default: true)'), includeTypes: z.boolean().optional().describe('Include TypeScript type definitions (default: true)'), });
- src/index.ts:194-207 (registration)Tool registration in the list of available tools returned by ListToolsRequestHandler, including name, description, and inputSchema.name: 'scaffold_consumer', description: 'Generate consumer code from a producer schema. Creates TypeScript functions, React hooks, or Zustand actions that correctly call MCP tools.', inputSchema: { type: 'object', properties: { producerDir: { type: 'string', description: 'Path to MCP server source directory' }, toolName: { type: 'string', description: 'Name of the tool to scaffold consumer for' }, target: { type: 'string', enum: ['typescript', 'javascript', 'react-hook', 'zustand-action'], description: 'Output target format' }, includeErrorHandling: { type: 'boolean', description: 'Include try/catch error handling' }, includeTypes: { type: 'boolean', description: 'Include TypeScript type definitions' }, }, required: ['producerDir', 'toolName'], }, },
- src/index.ts:405-442 (handler)Main handler for the scaffold_consumer tool call, which extracts the producer schema, invokes the scaffolding function, and formats the response.case 'scaffold_consumer': { const input = ScaffoldConsumerInput.parse(args); log(`Scaffolding consumer for tool: ${input.toolName}`); // Extract producer schemas to find the requested tool const producers = await extractProducerSchemas({ rootDir: input.producerDir }); const producer = producers.find(p => p.toolName === input.toolName); if (!producer) { throw new Error(`Tool "${input.toolName}" not found in ${input.producerDir}`); } const result = scaffoldConsumerFromProducer(producer, { target: input.target || 'typescript', includeErrorHandling: input.includeErrorHandling ?? true, includeTypes: input.includeTypes ?? true, includeJSDoc: true, }); log(`Generated ${input.target || 'typescript'} consumer code`); return { content: [ { type: 'text', text: JSON.stringify({ success: true, toolName: input.toolName, target: input.target || 'typescript', suggestedFilename: result.suggestedFilename, code: result.code, types: result.types, example: result.example, }, null, 2), }, ], }; }
- src/tools/scaffold.ts:35-79 (helper)Core helper function that generates consumer code (TypeScript/JS/React/Zustand) from a producer schema based on the specified target.export function scaffoldConsumerFromProducer( producer: ProducerSchema, options: ScaffoldOptions = { target: 'typescript' } ): ScaffoldResult { const { target, includeErrorHandling = true, includeTypes = true, functionPrefix = '', includeJSDoc = true } = options; const toolName = producer.toolName; const functionName = `${functionPrefix}${toCamelCase(toolName)}`; const inputProps = producer.inputSchema.properties || {}; const requiredArgs = producer.inputSchema.required || []; // Generate TypeScript interface for args const argsInterface = generateArgsInterface(toolName, inputProps, requiredArgs); // Generate the function based on target let code: string; let types: string | undefined; let example: string; switch (target) { case 'react-hook': ({ code, types, example } = generateReactHook(toolName, functionName, inputProps, requiredArgs, { includeErrorHandling, includeTypes, includeJSDoc, producer })); break; case 'zustand-action': ({ code, types, example } = generateZustandAction(toolName, functionName, inputProps, requiredArgs, { includeErrorHandling, includeTypes, includeJSDoc, producer })); break; case 'javascript': const jsResult = generateJavaScript(toolName, functionName, inputProps, requiredArgs, { includeErrorHandling, includeJSDoc, producer }); code = jsResult.code; example = jsResult.example; types = undefined; break; case 'typescript': default: ({ code, types, example } = generateTypeScript(toolName, functionName, inputProps, requiredArgs, { includeErrorHandling, includeTypes, includeJSDoc, producer })); break; } return { code, suggestedFilename: `use-${toKebabCase(toolName)}.${target === 'javascript' ? 'js' : 'ts'}`, types, example, }; }