scaffold_producer
Generate MCP tool definitions by analyzing how client code calls them, creating producer schema stubs from consumer usage patterns.
Instructions
Generate producer schema stub from consumer usage. Creates MCP tool definition based on how client code calls it.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| consumerDir | Yes | Path to consumer source directory | |
| toolName | Yes | Name of the tool to scaffold producer for | |
| includeHandler | No | Include handler stub |
Implementation Reference
- src/tools/scaffold.ts:84-130 (handler)Core handler function that implements the scaffold_producer tool logic: infers Zod schema from consumer arguments and generates MCP server.tool() code stub, optionally with a handler.export function scaffoldProducerFromConsumer( consumer: ConsumerSchema, options: { includeHandler?: boolean } = {} ): ScaffoldResult { const { includeHandler = true } = options; const toolName = consumer.toolName; const args = consumer.argumentsProvided; // Infer types from argument values (basic inference) const inferredSchema = inferSchemaFromArgs(args); const code = ` import { z } from 'zod'; // Tool: ${toolName} // Scaffolded from consumer at ${consumer.callSite.file}:${consumer.callSite.line} // @trace-contract PRODUCER (scaffolded) server.tool( '${toolName}', 'TODO: Add description', { ${Object.entries(inferredSchema) .map(([key, type]) => ` ${key}: ${type},`) .join('\n')} }, ${includeHandler ? ` async (args) => { // TODO: Implement handler // Consumer expects these properties: ${consumer.expectedProperties.join(', ')} return { content: [{ type: 'text', text: JSON.stringify({ ${consumer.expectedProperties.map(p => ` ${p}: null, // TODO`).join('\n')} }) }] }; }` : ' async (args) => { /* TODO */ }'} ); `.trim(); return { code, suggestedFilename: `${toKebabCase(toolName)}-tool.ts`, example: `// This tool is called by:\n// ${consumer.callSite.file}:${consumer.callSite.line}`, }; }
- src/index.ts:444-476 (handler)MCP server dispatch handler for 'scaffold_producer' tool call: validates input, traces consumer usage, invokes core scaffoldProducerFromConsumer, and formats response.case 'scaffold_producer': { const input = ScaffoldProducerInput.parse(args); log(`Scaffolding producer for tool: ${input.toolName}`); // Trace consumer usage to find the requested tool const consumers = await traceConsumerUsage({ rootDir: input.consumerDir }); const consumer = consumers.find(c => c.toolName === input.toolName); if (!consumer) { throw new Error(`Tool "${input.toolName}" not found in consumer code at ${input.consumerDir}`); } const result = scaffoldProducerFromConsumer(consumer, { includeHandler: input.includeHandler ?? true, }); log(`Generated producer schema stub`); return { content: [ { type: 'text', text: JSON.stringify({ success: true, toolName: input.toolName, suggestedFilename: result.suggestedFilename, code: result.code, example: result.example, }, null, 2), }, ], }; }
- src/index.ts:81-85 (schema)Zod input schema for validating arguments to the scaffold_producer tool.const ScaffoldProducerInput = z.object({ consumerDir: z.string().describe('Path to consumer source directory'), toolName: z.string().describe('Name of the tool to scaffold producer for'), includeHandler: z.boolean().optional().describe('Include handler stub (default: true)'), });
- src/index.ts:208-220 (registration)Tool registration metadata (name, description, inputSchema) returned by listTools request.{ name: 'scaffold_producer', description: 'Generate producer schema stub from consumer usage. Creates MCP tool definition based on how client code calls it.', inputSchema: { type: 'object', properties: { consumerDir: { type: 'string', description: 'Path to consumer source directory' }, toolName: { type: 'string', description: 'Name of the tool to scaffold producer for' }, includeHandler: { type: 'boolean', description: 'Include handler stub' }, }, required: ['consumerDir', 'toolName'], }, },
- src/tools/index.ts:14-18 (registration)Re-export of scaffoldProducerFromConsumer function, imported into main index.ts for tool handler.scaffoldConsumerFromProducer, scaffoldProducerFromConsumer, type ScaffoldOptions, type ScaffoldResult, } from './scaffold.js';