Skip to main content
Glama

documcp

by tosin2013
setup-structure.ts10.9 kB
import { promises as fs } from 'fs'; import path from 'path'; import { z } from 'zod'; import { MCPToolResponse, formatMCPResponse } from '../types/api.js'; const inputSchema = z.object({ path: z.string(), ssg: z.enum(['jekyll', 'hugo', 'docusaurus', 'mkdocs', 'eleventy']), includeExamples: z.boolean().optional().default(true), }); // Diataxis structure based on ADR-004 const DIATAXIS_STRUCTURE = { tutorials: { description: 'Learning-oriented guides for newcomers', example: 'getting-started.md', }, 'how-to': { description: 'Task-oriented guides for specific goals', example: 'deploy-to-production.md', }, reference: { description: 'Information-oriented technical descriptions', example: 'api-documentation.md', }, explanation: { description: 'Understanding-oriented conceptual discussions', example: 'architecture-overview.md', }, }; export async function setupStructure(args: unknown): Promise<{ content: any[] }> { const startTime = Date.now(); const { path: docsPath, ssg, includeExamples } = inputSchema.parse(args); try { const createdDirs: string[] = []; const createdFiles: string[] = []; // Create base docs directory await fs.mkdir(docsPath, { recursive: true }); // Create Diataxis structure for (const [category, info] of Object.entries(DIATAXIS_STRUCTURE)) { const categoryPath = path.join(docsPath, category); await fs.mkdir(categoryPath, { recursive: true }); createdDirs.push(categoryPath); // Create index file for category const indexPath = path.join(categoryPath, 'index.md'); const indexContent = generateCategoryIndex(category, info.description, ssg, includeExamples); await fs.writeFile(indexPath, indexContent); createdFiles.push(indexPath); // Create example content if requested if (includeExamples) { const examplePath = path.join(categoryPath, info.example); const exampleContent = generateExampleContent(category, info.example, ssg); await fs.writeFile(examplePath, exampleContent); createdFiles.push(examplePath); } } // Create root index const rootIndexPath = path.join(docsPath, 'index.md'); const rootIndexContent = generateRootIndex(ssg); await fs.writeFile(rootIndexPath, rootIndexContent); createdFiles.push(rootIndexPath); const structureResult = { docsPath, ssg, includeExamples, directoriesCreated: createdDirs, filesCreated: createdFiles, diataxisCategories: Object.keys(DIATAXIS_STRUCTURE), totalDirectories: createdDirs.length, totalFiles: createdFiles.length, }; const response: MCPToolResponse<typeof structureResult> = { success: true, data: structureResult, metadata: { toolVersion: '1.0.0', executionTime: Date.now() - startTime, timestamp: new Date().toISOString(), }, recommendations: [ { type: 'info', title: 'Diataxis Structure Created', description: `Successfully created ${createdDirs.length} directories and ${createdFiles.length} files`, }, ], nextSteps: [ { action: 'Setup GitHub Pages Deployment', toolRequired: 'deploy_pages', description: 'Create automated deployment workflow', priority: 'medium', }, ], }; return formatMCPResponse(response); } catch (error) { const errorResponse: MCPToolResponse = { success: false, error: { code: 'STRUCTURE_SETUP_FAILED', message: `Failed to setup structure: ${error}`, resolution: 'Ensure the documentation path is writable and accessible', }, metadata: { toolVersion: '1.0.0', executionTime: Date.now() - startTime, timestamp: new Date().toISOString(), }, }; return formatMCPResponse(errorResponse); } } function generateCategoryIndex( category: string, description: string, ssg: string, includeExamples: boolean = true, ): string { const title = category.charAt(0).toUpperCase() + category.slice(1).replace('-', ' '); let frontmatter = ''; switch (ssg) { case 'docusaurus': frontmatter = `--- id: ${category}-index title: ${title} sidebar_label: ${title} ---\n\n`; break; case 'mkdocs': case 'jekyll': case 'hugo': frontmatter = `--- title: ${title} description: ${description} ---\n\n`; break; } return `${frontmatter}# ${title} ${description} ## Available Guides This section contains ${category} documentation following the Diataxis framework. ${generateDiataxisExplanation(category)} ## Contents ${ includeExamples ? `- [Example: ${DIATAXIS_STRUCTURE[category as keyof typeof DIATAXIS_STRUCTURE].example}](./${ DIATAXIS_STRUCTURE[category as keyof typeof DIATAXIS_STRUCTURE].example })` : '- Coming soon...' } `; } function generateExampleContent(category: string, filename: string, ssg: string): string { const title = filename .replace('.md', '') .replace(/-/g, ' ') .split(' ') .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) .join(' '); let frontmatter = ''; switch (ssg) { case 'docusaurus': frontmatter = `--- id: ${filename.replace('.md', '')} title: ${title} sidebar_label: ${title} ---\n\n`; break; default: frontmatter = `--- title: ${title} ---\n\n`; break; } let content = ''; switch (category) { case 'tutorials': content = `# ${title} This tutorial will guide you through the process step by step. ## Prerequisites Before you begin, ensure you have: - Requirement 1 - Requirement 2 ## Step 1: Initial Setup Start by... ## Step 2: Configuration Next, configure... ## Step 3: Verification Finally, verify... ## Summary In this tutorial, you learned how to: - Achievement 1 - Achievement 2 - Achievement 3 ## Next Steps - Explore [How-To Guides](../how-to/) - Read the [API Reference](../reference/)`; break; case 'how-to': content = `# ${title} This guide shows you how to accomplish a specific task. ## Prerequisites - Prerequisite 1 - Prerequisite 2 ## Steps ### 1. Prepare your environment \`\`\`bash # Example command echo "Setup environment" \`\`\` ### 2. Execute the task \`\`\`bash # Main command echo "Execute task" \`\`\` ### 3. Verify results \`\`\`bash # Verification command echo "Verify success" \`\`\` ## Troubleshooting If you encounter issues: - Check condition 1 - Verify setting 2 ## Related Guides - [Another How-To Guide](./another-guide.md) - [Reference Documentation](../reference/)`; break; case 'reference': content = `# ${title} Technical reference documentation. ## Overview This document provides complete reference information for... ## API Endpoints ### GET /api/resource Retrieves... **Parameters:** - \`param1\` (string, required): Description - \`param2\` (number, optional): Description **Response:** \`\`\`json { "field1": "value", "field2": 123 } \`\`\` ### POST /api/resource Creates... ## Configuration Options | Option | Type | Default | Description | |--------|------|---------|-------------| | option1 | string | "default" | Description of option1 | | option2 | boolean | false | Description of option2 | ## Error Codes | Code | Description | Resolution | |------|-------------|------------| | E001 | Error description | How to fix | | E002 | Error description | How to fix |`; break; case 'explanation': content = `# ${title} This document explains the concepts and reasoning behind... ## Introduction Understanding the architecture requires knowledge of... ## Core Concepts ### Concept 1 Explanation of the first core concept... ### Concept 2 Explanation of the second core concept... ## Design Decisions ### Why This Approach? We chose this approach because... ### Trade-offs The main trade-offs include: - Trade-off 1: Benefit vs Cost - Trade-off 2: Benefit vs Cost ## Comparison with Alternatives | Approach | Pros | Cons | |----------|------|------| | Our Approach | Pro 1, Pro 2 | Con 1 | | Alternative 1 | Pro 1 | Con 1, Con 2 | | Alternative 2 | Pro 1, Pro 2 | Con 1 | ## Further Reading - [Related Tutorial](../tutorials/) - [Implementation Guide](../how-to/)`; break; } return `${frontmatter}${content}`; } function generateRootIndex(ssg: string): string { let frontmatter = ''; switch (ssg) { case 'docusaurus': frontmatter = `--- id: intro title: Documentation sidebar_position: 1 ---\n\n`; break; default: frontmatter = `--- title: Documentation ---\n\n`; break; } return `${frontmatter}# Documentation Welcome to our documentation! This site follows the [Diataxis](https://diataxis.fr/) framework to provide clear, well-organized documentation. ## Documentation Structure Our documentation is organized into four distinct sections: ### 📚 [Tutorials](./tutorials/) Learning-oriented guides that take you through a process step by step. Perfect for newcomers who want to get started. ### 🔧 [How-To Guides](./how-to/) Task-oriented recipes that help you accomplish specific goals. Ideal when you know what you want to do. ### 📖 [Reference](./reference/) Information-oriented technical descriptions of the system. Essential when you need to look up specific details. ### 💡 [Explanation](./explanation/) Understanding-oriented discussions that clarify and illuminate topics. Great for deepening your knowledge. ## Quick Start New to this project? Start with our [Getting Started Tutorial](./tutorials/getting-started.md). ## Contributing We welcome contributions to our documentation! Please see our [Contributing Guide](./how-to/contribute.md) for details. `; } function generateDiataxisExplanation(category: string): string { const explanations: Record<string, string> = { tutorials: ` **Tutorials** are learning-oriented and help newcomers get started: - Take the reader through a process step by step - Focus on learning by doing - Ensure the reader succeeds in accomplishing something - Build confidence through success`, 'how-to': ` **How-To Guides** are task-oriented and help users accomplish specific goals: - Solve specific problems - Assume some knowledge and experience - Provide a series of steps - Focus on results`, reference: ` **Reference** documentation is information-oriented: - Describe the machinery - Be accurate and complete - Focus on describing, not explaining - Structure content for finding information`, explanation: ` **Explanation** documentation is understanding-oriented: - Clarify and illuminate a topic - Provide context and background - Discuss alternatives and opinions - Focus on understanding, not instruction`, }; return explanations[category] || ''; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tosin2013/documcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server