comment_contract
Add cross-reference comments to document contract relationships between validated producer and consumer pairs in both source files.
Instructions
Add cross-reference comments to validated producer/consumer pairs. Documents the contract relationship in both files.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| producerDir | Yes | Path to MCP server source directory | |
| consumerDir | Yes | Path to consumer source directory | |
| toolName | Yes | Name of the validated tool | |
| dryRun | No | Preview comments without writing to files (default: true) | |
| style | No | Comment style |
Implementation Reference
- src/index.ts:478-551 (handler)Executes the 'comment_contract' tool: parses args, extracts schemas, finds match, calls previewContractComments (dryRun) or addContractComments.case 'comment_contract': { const input = CommentContractInput.parse(args); log(`Commenting contract for tool: ${input.toolName}`); // Get both producer and consumer const producers = await extractProducerSchemas({ rootDir: input.producerDir }); const consumers = await traceConsumerUsage({ rootDir: input.consumerDir }); const producer = producers.find(p => p.toolName === input.toolName); const consumer = consumers.find(c => c.toolName === input.toolName); if (!producer) { throw new Error(`Tool "${input.toolName}" not found in producer at ${input.producerDir}`); } if (!consumer) { throw new Error(`Tool "${input.toolName}" not found in consumer at ${input.consumerDir}`); } const match = { toolName: input.toolName, producerLocation: producer.location, consumerLocation: consumer.callSite, }; const commentOptions = { match, producer, consumer, style: input.style || 'block' as const, includeTimestamp: true, }; if (input.dryRun !== false) { // Preview mode (default) const preview = previewContractComments(commentOptions); return { content: [ { type: 'text', text: JSON.stringify({ success: true, mode: 'preview', toolName: input.toolName, producerPreview: preview.producerPreview, consumerPreview: preview.consumerPreview, note: 'Set dryRun: false to actually add these comments to files', }, null, 2), }, ], }; } else { // Actually add comments const result = await addContractComments(commentOptions); return { content: [ { type: 'text', text: JSON.stringify({ success: result.success, mode: 'applied', toolName: input.toolName, producerFile: result.producerFile, consumerFile: result.consumerFile, producerComment: result.producerComment, consumerComment: result.consumerComment, error: result.error, }, null, 2), }, ], }; } }
- src/index.ts:87-93 (schema)Zod input schema for comment_contract tool.const CommentContractInput = z.object({ producerDir: z.string().describe('Path to MCP server source directory'), consumerDir: z.string().describe('Path to consumer source directory'), toolName: z.string().describe('Name of the validated tool'), dryRun: z.boolean().optional().describe('Preview comments without writing to files (default: true)'), style: z.enum(['jsdoc', 'inline', 'block']).optional().describe('Comment style (default: block)'), });
- src/index.ts:221-235 (registration)Tool registration in ListTools response, including name, description, and inputSchema.{ name: 'comment_contract', description: 'Add cross-reference comments to validated producer/consumer pairs. Documents the contract relationship in both files.', inputSchema: { type: 'object', properties: { producerDir: { type: 'string', description: 'Path to MCP server source directory' }, consumerDir: { type: 'string', description: 'Path to consumer source directory' }, toolName: { type: 'string', description: 'Name of the validated tool' }, dryRun: { type: 'boolean', description: 'Preview comments without writing to files (default: true)' }, style: { type: 'string', enum: ['jsdoc', 'inline', 'block'], description: 'Comment style' }, }, required: ['producerDir', 'consumerDir', 'toolName'], }, },
- Helper function to actually add contract comments to source files using ts-morph, modifies producer and consumer files.export async function addContractComments(options: ContractCommentOptions): Promise<CommentResult> { const { match, producer, consumer } = options; const { producerComment, consumerComment } = generateContractComments(options); const project = new Project({ skipAddingFilesFromTsConfig: true, }); try { // Add comment to producer file const producerFile = project.addSourceFileAtPath(producer.location.file); const producerNode = findNodeAtLine(producerFile, producer.location.line); if (producerNode) { // Add comment before the tool definition producerNode.replaceWithText(`${producerComment}\n${producerNode.getText()}`); } // Add comment to consumer file const consumerFile = project.addSourceFileAtPath(consumer.callSite.file); const consumerNode = findNodeAtLine(consumerFile, consumer.callSite.line); if (consumerNode) { // Add comment before the callTool invocation consumerNode.replaceWithText(`${consumerComment}\n${consumerNode.getText()}`); } // Save changes await project.save(); return { success: true, producerFile: producer.location.file, consumerFile: consumer.callSite.file, producerComment, consumerComment, }; } catch (error) { return { success: false, producerFile: producer.location.file, consumerFile: consumer.callSite.file, producerComment, consumerComment, error: error instanceof Error ? error.message : String(error), }; } }
- Helper function to preview contract comments without modifying files.export function previewContractComments(options: ContractCommentOptions): { producerPreview: string; consumerPreview: string; } { const { producerComment, consumerComment } = generateContractComments(options); const { producer, consumer } = options; return { producerPreview: `// At ${producer.location.file}:${producer.location.line}\n${producerComment}`, consumerPreview: `// At ${consumer.callSite.file}:${consumer.callSite.line}\n${consumerComment}`, }; }