UNPKG

@bottobot/td-mcp

Version:

TouchDesigner MCP Server v2.8.0 - 21 MCP tools, 629 operators with clean parameter data, 69 Python API classes, 14 tutorials, 32 workflow patterns. Includes version system, experimental techniques KB, core tool enhancements, and experimental build support

168 lines (145 loc) 5.09 kB
/** * Get Tutorial Tool - Retrieves full content from a TouchDesigner tutorial. * Returns sections, table of contents, code blocks, images, and related links. * @module tools/get_tutorial */ import { z } from "zod"; // Tool schema export const schema = { title: "Get TouchDesigner Tutorial", description: "Get detailed content from a TouchDesigner tutorial", inputSchema: { name: z.string().describe("Tutorial name (e.g., 'Anatomy of a CHOP', 'Write a GLSL TOP')"), include_content: z.boolean().optional().describe("Include full tutorial content sections"), include_toc: z.boolean().optional().describe("Include table of contents"), include_links: z.boolean().optional().describe("Include related links") } }; // Tool handler export async function handler({ name, include_content = true, include_toc = true, include_links = true }, { operatorDataManager }) { if (!operatorDataManager) { return { content: [{ type: "text", text: "Wiki system not available. Server may still be initializing." }] }; } const tutorial = await operatorDataManager.getTutorial(name); if (!tutorial) { // Try to list available tutorials const { tutorials } = await operatorDataManager.listTutorials({ limit: 10 }); const tutorialList = tutorials.map(t => `• ${t.name}`).join('\n'); return { content: [{ type: "text", text: `Tutorial '${name}' not found.\n\nAvailable tutorials:\n${tutorialList}\n\nUse 'search_tutorials' to search by keyword, or 'list_tutorials' to see all tutorials.` }] }; } let text = `# ${tutorial.displayName || tutorial.name}\n`; text += `**Category:** ${tutorial.category}\n\n`; // Description if (tutorial.description) { text += `## Description\n${tutorial.description}\n\n`; } // Summary if (tutorial.summary) { text += `## Summary\n${tutorial.summary}\n\n`; } // Table of Contents if (include_toc && tutorial.content?.tableOfContents && tutorial.content.tableOfContents.length > 0) { text += `## Table of Contents\n`; tutorial.content.tableOfContents.forEach(item => { text += `${item.number ? item.number + '.' : '•'} ${item.text}\n`; }); text += '\n'; } // Content Sections if (include_content && tutorial.content?.sections && tutorial.content.sections.length > 0) { text += `## Content\n\n`; tutorial.content.sections.forEach(section => { // Section title text += `### ${section.title}\n\n`; // Section content if (section.content && section.content.length > 0) { section.content.forEach(item => { switch (item.type) { case 'paragraph': text += `${item.text}\n\n`; break; case 'unordered-list': if (item.items) { item.items.forEach(listItem => { text += `• ${listItem}\n`; }); text += '\n'; } break; case 'ordered-list': if (item.items) { item.items.forEach((listItem, index) => { text += `${index + 1}. ${listItem}\n`; }); text += '\n'; } break; case 'code': text += '```' + (item.language || '') + '\n'; text += item.text + '\n'; text += '```\n\n'; break; case 'subsection': text += `#### ${item.title}\n\n`; break; default: if (item.text) { text += `${item.text}\n\n`; } } }); } }); } else if (include_content) { text += `*Note: This tutorial has no detailed content sections available.*\n\n`; } // Related Links if (include_links && tutorial.content?.relatedLinks && tutorial.content.relatedLinks.length > 0) { text += `## Related Links\n`; tutorial.content.relatedLinks.forEach(link => { text += `• [${link.text}](${link.href})\n`; }); text += '\n'; } // Images if (tutorial.content?.images && tutorial.content.images.length > 0) { text += `## Images\n`; tutorial.content.images.forEach(img => { text += `• ${img.alt || 'Image'}: ${img.src}\n`; if (img.caption) { text += ` Caption: ${img.caption}\n`; } }); text += '\n'; } // Keywords/Tags if (tutorial.keywords && tutorial.keywords.length > 0) { text += `## Keywords\n${tutorial.keywords.join(', ')}\n\n`; } // Metadata text += `---\n`; text += `*Source: TouchDesigner HTM documentation`; if (tutorial.lastUpdated) { text += ` (updated ${new Date(tutorial.lastUpdated).toLocaleDateString()})`; } if (tutorial.content?.sections) { text += ` | ${tutorial.content.sections.length} sections`; } text += `*\n`; return { content: [{ type: "text", text }] }; }