comment_contract
Add cross-reference comments to validated producer and consumer pairs, documenting the contract relationship in both source files.
Instructions
Add cross-reference comments to validated producer/consumer pairs. Documents the contract relationship in both files.
Input 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:221-235 (registration)Tool registration for 'comment_contract' in the MCP tool listing (ListToolsRequestSchema). Defines name, description, and inputSchema for the tool.
{ 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'], }, }, - src/index.ts:87-93 (schema)Zod schema 'CommentContractInput' defining input validation for the comment_contract tool: producerDir, consumerDir, toolName (required), dryRun (optional boolean, default true), style (optional enum 'jsdoc'|'inline'|'block', default 'block').
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:478-551 (handler)Handler case for 'comment_contract' in CallToolRequestSchema switch. Parses input via CommentContractInput, extracts producer schema and consumer usage, finds matching tool by name, then either previews comments (dryRun default) or writes them to files via 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/tools/contract-comments.ts:94-141 (handler)Core implementation of addContractComments - writes cross-reference comments to producer and consumer files using ts-morph. Returns CommentResult with success status, file paths, and generated comments.
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), }; } } - Preview function previewContractComments that shows what comments would be added without modifying files. Returns producer and consumer preview strings showing file paths and generated comments.
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}`, }; }