scaffold_producer
Generate MCP tool producer schemas from consumer code usage. Creates tool definitions based on how client applications call the tool.
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 generates a producer schema stub from traced consumer usage, inferring input schema and providing a handler template.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 the scaffold_producer tool: validates input, traces consumer usages, finds the matching consumer, calls the core scaffold function, and formats the 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 validation for the scaffold_producer tool arguments.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 metadata registration in the listTools response, including name, description, and JSON schema for input validation.{ 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'], }, },