#
tokens: 34640/50000 1/274 files (page 28/29)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 28 of 29. Use http://codebase.md/tosin2013/documcp?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .dockerignore
├── .eslintignore
├── .eslintrc.json
├── .github
│   ├── agents
│   │   ├── documcp-ast.md
│   │   ├── documcp-deploy.md
│   │   ├── documcp-memory.md
│   │   ├── documcp-test.md
│   │   └── documcp-tool.md
│   ├── copilot-instructions.md
│   ├── dependabot.yml
│   ├── ISSUE_TEMPLATE
│   │   ├── automated-changelog.md
│   │   ├── bug_report.md
│   │   ├── bug_report.yml
│   │   ├── documentation_issue.md
│   │   ├── feature_request.md
│   │   ├── feature_request.yml
│   │   ├── npm-publishing-fix.md
│   │   └── release_improvements.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── release-drafter.yml
│   └── workflows
│       ├── auto-merge.yml
│       ├── ci.yml
│       ├── codeql.yml
│       ├── dependency-review.yml
│       ├── deploy-docs.yml
│       ├── README.md
│       ├── release-drafter.yml
│       └── release.yml
├── .gitignore
├── .husky
│   ├── commit-msg
│   └── pre-commit
├── .linkcheck.config.json
├── .markdown-link-check.json
├── .nvmrc
├── .pre-commit-config.yaml
├── .versionrc.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── commitlint.config.js
├── CONTRIBUTING.md
├── docker-compose.docs.yml
├── Dockerfile.docs
├── docs
│   ├── .docusaurus
│   │   ├── docusaurus-plugin-content-docs
│   │   │   └── default
│   │   │       └── __mdx-loader-dependency.json
│   │   └── docusaurus-plugin-content-pages
│   │       └── default
│   │           └── __plugin.json
│   ├── adrs
│   │   ├── 001-mcp-server-architecture.md
│   │   ├── 002-repository-analysis-engine.md
│   │   ├── 003-static-site-generator-recommendation-engine.md
│   │   ├── 004-diataxis-framework-integration.md
│   │   ├── 005-github-pages-deployment-automation.md
│   │   ├── 006-mcp-tools-api-design.md
│   │   ├── 007-mcp-prompts-and-resources-integration.md
│   │   ├── 008-intelligent-content-population-engine.md
│   │   ├── 009-content-accuracy-validation-framework.md
│   │   ├── 010-mcp-resource-pattern-redesign.md
│   │   └── README.md
│   ├── api
│   │   ├── .nojekyll
│   │   ├── assets
│   │   │   ├── hierarchy.js
│   │   │   ├── highlight.css
│   │   │   ├── icons.js
│   │   │   ├── icons.svg
│   │   │   ├── main.js
│   │   │   ├── navigation.js
│   │   │   ├── search.js
│   │   │   └── style.css
│   │   ├── hierarchy.html
│   │   ├── index.html
│   │   ├── modules.html
│   │   └── variables
│   │       └── TOOLS.html
│   ├── assets
│   │   └── logo.svg
│   ├── development
│   │   └── MCP_INSPECTOR_TESTING.md
│   ├── docusaurus.config.js
│   ├── explanation
│   │   ├── architecture.md
│   │   └── index.md
│   ├── guides
│   │   ├── link-validation.md
│   │   ├── playwright-integration.md
│   │   └── playwright-testing-workflow.md
│   ├── how-to
│   │   ├── analytics-setup.md
│   │   ├── custom-domains.md
│   │   ├── documentation-freshness-tracking.md
│   │   ├── github-pages-deployment.md
│   │   ├── index.md
│   │   ├── local-testing.md
│   │   ├── performance-optimization.md
│   │   ├── prompting-guide.md
│   │   ├── repository-analysis.md
│   │   ├── seo-optimization.md
│   │   ├── site-monitoring.md
│   │   ├── troubleshooting.md
│   │   └── usage-examples.md
│   ├── index.md
│   ├── knowledge-graph.md
│   ├── package-lock.json
│   ├── package.json
│   ├── phase-2-intelligence.md
│   ├── reference
│   │   ├── api-overview.md
│   │   ├── cli.md
│   │   ├── configuration.md
│   │   ├── deploy-pages.md
│   │   ├── index.md
│   │   ├── mcp-tools.md
│   │   └── prompt-templates.md
│   ├── research
│   │   ├── cross-domain-integration
│   │   │   └── README.md
│   │   ├── domain-1-mcp-architecture
│   │   │   ├── index.md
│   │   │   └── mcp-performance-research.md
│   │   ├── domain-2-repository-analysis
│   │   │   └── README.md
│   │   ├── domain-3-ssg-recommendation
│   │   │   ├── index.md
│   │   │   └── ssg-performance-analysis.md
│   │   ├── domain-4-diataxis-integration
│   │   │   └── README.md
│   │   ├── domain-5-github-deployment
│   │   │   ├── github-pages-security-analysis.md
│   │   │   └── index.md
│   │   ├── domain-6-api-design
│   │   │   └── README.md
│   │   ├── README.md
│   │   ├── research-integration-summary-2025-01-14.md
│   │   ├── research-progress-template.md
│   │   └── research-questions-2025-01-14.md
│   ├── robots.txt
│   ├── sidebars.js
│   ├── sitemap.xml
│   ├── src
│   │   └── css
│   │       └── custom.css
│   └── tutorials
│       ├── development-setup.md
│       ├── environment-setup.md
│       ├── first-deployment.md
│       ├── getting-started.md
│       ├── index.md
│       ├── memory-workflows.md
│       └── user-onboarding.md
├── jest.config.js
├── LICENSE
├── Makefile
├── MCP_PHASE2_IMPLEMENTATION.md
├── mcp-config-example.json
├── mcp.json
├── package-lock.json
├── package.json
├── README.md
├── release.sh
├── scripts
│   └── check-package-structure.cjs
├── SECURITY.md
├── setup-precommit.sh
├── src
│   ├── benchmarks
│   │   └── performance.ts
│   ├── index.ts
│   ├── memory
│   │   ├── contextual-retrieval.ts
│   │   ├── deployment-analytics.ts
│   │   ├── enhanced-manager.ts
│   │   ├── export-import.ts
│   │   ├── freshness-kg-integration.ts
│   │   ├── index.ts
│   │   ├── integration.ts
│   │   ├── kg-code-integration.ts
│   │   ├── kg-health.ts
│   │   ├── kg-integration.ts
│   │   ├── kg-link-validator.ts
│   │   ├── kg-storage.ts
│   │   ├── knowledge-graph.ts
│   │   ├── learning.ts
│   │   ├── manager.ts
│   │   ├── multi-agent-sharing.ts
│   │   ├── pruning.ts
│   │   ├── schemas.ts
│   │   ├── storage.ts
│   │   ├── temporal-analysis.ts
│   │   ├── user-preferences.ts
│   │   └── visualization.ts
│   ├── prompts
│   │   └── technical-writer-prompts.ts
│   ├── scripts
│   │   └── benchmark.ts
│   ├── templates
│   │   └── playwright
│   │       ├── accessibility.spec.template.ts
│   │       ├── Dockerfile.template
│   │       ├── docs-e2e.workflow.template.yml
│   │       ├── link-validation.spec.template.ts
│   │       └── playwright.config.template.ts
│   ├── tools
│   │   ├── analyze-deployments.ts
│   │   ├── analyze-readme.ts
│   │   ├── analyze-repository.ts
│   │   ├── check-documentation-links.ts
│   │   ├── deploy-pages.ts
│   │   ├── detect-gaps.ts
│   │   ├── evaluate-readme-health.ts
│   │   ├── generate-config.ts
│   │   ├── generate-contextual-content.ts
│   │   ├── generate-llm-context.ts
│   │   ├── generate-readme-template.ts
│   │   ├── generate-technical-writer-prompts.ts
│   │   ├── kg-health-check.ts
│   │   ├── manage-preferences.ts
│   │   ├── manage-sitemap.ts
│   │   ├── optimize-readme.ts
│   │   ├── populate-content.ts
│   │   ├── readme-best-practices.ts
│   │   ├── recommend-ssg.ts
│   │   ├── setup-playwright-tests.ts
│   │   ├── setup-structure.ts
│   │   ├── sync-code-to-docs.ts
│   │   ├── test-local-deployment.ts
│   │   ├── track-documentation-freshness.ts
│   │   ├── update-existing-documentation.ts
│   │   ├── validate-content.ts
│   │   ├── validate-documentation-freshness.ts
│   │   ├── validate-readme-checklist.ts
│   │   └── verify-deployment.ts
│   ├── types
│   │   └── api.ts
│   ├── utils
│   │   ├── ast-analyzer.ts
│   │   ├── code-scanner.ts
│   │   ├── content-extractor.ts
│   │   ├── drift-detector.ts
│   │   ├── freshness-tracker.ts
│   │   ├── language-parsers-simple.ts
│   │   ├── permission-checker.ts
│   │   └── sitemap-generator.ts
│   └── workflows
│       └── documentation-workflow.ts
├── test-docs-local.sh
├── tests
│   ├── api
│   │   └── mcp-responses.test.ts
│   ├── benchmarks
│   │   └── performance.test.ts
│   ├── edge-cases
│   │   └── error-handling.test.ts
│   ├── functional
│   │   └── tools.test.ts
│   ├── integration
│   │   ├── kg-documentation-workflow.test.ts
│   │   ├── knowledge-graph-workflow.test.ts
│   │   ├── mcp-readme-tools.test.ts
│   │   ├── memory-mcp-tools.test.ts
│   │   ├── readme-technical-writer.test.ts
│   │   └── workflow.test.ts
│   ├── memory
│   │   ├── contextual-retrieval.test.ts
│   │   ├── enhanced-manager.test.ts
│   │   ├── export-import.test.ts
│   │   ├── freshness-kg-integration.test.ts
│   │   ├── kg-code-integration.test.ts
│   │   ├── kg-health.test.ts
│   │   ├── kg-link-validator.test.ts
│   │   ├── kg-storage-validation.test.ts
│   │   ├── kg-storage.test.ts
│   │   ├── knowledge-graph-enhanced.test.ts
│   │   ├── knowledge-graph.test.ts
│   │   ├── learning.test.ts
│   │   ├── manager-advanced.test.ts
│   │   ├── manager.test.ts
│   │   ├── mcp-resource-integration.test.ts
│   │   ├── mcp-tool-persistence.test.ts
│   │   ├── schemas.test.ts
│   │   ├── storage.test.ts
│   │   ├── temporal-analysis.test.ts
│   │   └── user-preferences.test.ts
│   ├── performance
│   │   ├── memory-load-testing.test.ts
│   │   └── memory-stress-testing.test.ts
│   ├── prompts
│   │   ├── guided-workflow-prompts.test.ts
│   │   └── technical-writer-prompts.test.ts
│   ├── server.test.ts
│   ├── setup.ts
│   ├── tools
│   │   ├── all-tools.test.ts
│   │   ├── analyze-coverage.test.ts
│   │   ├── analyze-deployments.test.ts
│   │   ├── analyze-readme.test.ts
│   │   ├── analyze-repository.test.ts
│   │   ├── check-documentation-links.test.ts
│   │   ├── deploy-pages-kg-retrieval.test.ts
│   │   ├── deploy-pages-tracking.test.ts
│   │   ├── deploy-pages.test.ts
│   │   ├── detect-gaps.test.ts
│   │   ├── evaluate-readme-health.test.ts
│   │   ├── generate-contextual-content.test.ts
│   │   ├── generate-llm-context.test.ts
│   │   ├── generate-readme-template.test.ts
│   │   ├── generate-technical-writer-prompts.test.ts
│   │   ├── kg-health-check.test.ts
│   │   ├── manage-sitemap.test.ts
│   │   ├── optimize-readme.test.ts
│   │   ├── readme-best-practices.test.ts
│   │   ├── recommend-ssg-historical.test.ts
│   │   ├── recommend-ssg-preferences.test.ts
│   │   ├── recommend-ssg.test.ts
│   │   ├── simple-coverage.test.ts
│   │   ├── sync-code-to-docs.test.ts
│   │   ├── test-local-deployment.test.ts
│   │   ├── tool-error-handling.test.ts
│   │   ├── track-documentation-freshness.test.ts
│   │   ├── validate-content.test.ts
│   │   ├── validate-documentation-freshness.test.ts
│   │   └── validate-readme-checklist.test.ts
│   ├── types
│   │   └── type-safety.test.ts
│   └── utils
│       ├── ast-analyzer.test.ts
│       ├── content-extractor.test.ts
│       ├── drift-detector.test.ts
│       ├── freshness-tracker.test.ts
│       └── sitemap-generator.test.ts
├── tsconfig.json
└── typedoc.json
```

# Files

--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------

```typescript
   1 | #!/usr/bin/env node
   2 | import { Server } from "@modelcontextprotocol/sdk/server/index.js";
   3 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
   4 | import {
   5 |   CallToolRequestSchema,
   6 |   ListToolsRequestSchema,
   7 |   ListPromptsRequestSchema,
   8 |   GetPromptRequestSchema,
   9 |   ListResourcesRequestSchema,
  10 |   ReadResourceRequestSchema,
  11 |   ListRootsRequestSchema,
  12 | } from "@modelcontextprotocol/sdk/types.js";
  13 | import { z } from "zod";
  14 | import { zodToJsonSchema } from "zod-to-json-schema";
  15 | import { readFileSync } from "fs";
  16 | import { fileURLToPath } from "url";
  17 | import path, { dirname, join } from "path";
  18 | 
  19 | import { analyzeRepository } from "./tools/analyze-repository.js";
  20 | import { recommendSSG } from "./tools/recommend-ssg.js";
  21 | import { generateConfig } from "./tools/generate-config.js";
  22 | import { setupStructure } from "./tools/setup-structure.js";
  23 | import { deployPages } from "./tools/deploy-pages.js";
  24 | import { verifyDeployment } from "./tools/verify-deployment.js";
  25 | import { setupPlaywrightTests } from "./tools/setup-playwright-tests.js";
  26 | import { handlePopulateDiataxisContent } from "./tools/populate-content.js";
  27 | import {
  28 |   handleValidateDiataxisContent,
  29 |   validateGeneralContent,
  30 | } from "./tools/validate-content.js";
  31 | import { handleUpdateExistingDocumentation } from "./tools/update-existing-documentation.js";
  32 | import { detectDocumentationGaps } from "./tools/detect-gaps.js";
  33 | import { testLocalDeployment } from "./tools/test-local-deployment.js";
  34 | import { evaluateReadmeHealth } from "./tools/evaluate-readme-health.js";
  35 | import { readmeBestPractices } from "./tools/readme-best-practices.js";
  36 | import { checkDocumentationLinks } from "./tools/check-documentation-links.js";
  37 | import { generateReadmeTemplate } from "./tools/generate-readme-template.js";
  38 | import { validateReadmeChecklist } from "./tools/validate-readme-checklist.js";
  39 | import { analyzeReadme } from "./tools/analyze-readme.js";
  40 | import { optimizeReadme } from "./tools/optimize-readme.js";
  41 | import { managePreferences } from "./tools/manage-preferences.js";
  42 | import { analyzeDeployments } from "./tools/analyze-deployments.js";
  43 | import { handleSyncCodeToDocs } from "./tools/sync-code-to-docs.js";
  44 | import { handleGenerateContextualContent } from "./tools/generate-contextual-content.js";
  45 | import { trackDocumentationFreshness } from "./tools/track-documentation-freshness.js";
  46 | import { validateDocumentationFreshness } from "./tools/validate-documentation-freshness.js";
  47 | import {
  48 |   manageSitemap,
  49 |   ManageSitemapInputSchema,
  50 | } from "./tools/manage-sitemap.js";
  51 | import {
  52 |   generateLLMContext,
  53 |   GenerateLLMContextInputSchema,
  54 |   setToolDefinitions,
  55 | } from "./tools/generate-llm-context.js";
  56 | import { formatMCPResponse } from "./types/api.js";
  57 | import {
  58 |   isPathAllowed,
  59 |   getPermissionDeniedMessage,
  60 | } from "./utils/permission-checker.js";
  61 | import { promises as fs } from "fs";
  62 | import { generateTechnicalWriterPrompts } from "./prompts/technical-writer-prompts.js";
  63 | import {
  64 |   DOCUMENTATION_WORKFLOWS,
  65 |   WORKFLOW_EXECUTION_GUIDANCE,
  66 |   WORKFLOW_METADATA,
  67 | } from "./workflows/documentation-workflow.js";
  68 | import {
  69 |   initializeMemory,
  70 |   rememberAnalysis,
  71 |   rememberRecommendation,
  72 |   getProjectInsights,
  73 |   getSimilarProjects,
  74 |   getMemoryStatistics,
  75 |   exportMemories,
  76 |   cleanupOldMemories,
  77 |   memoryTools,
  78 | } from "./memory/index.js";
  79 | 
  80 | // Get version from package.json
  81 | const __filename = fileURLToPath(import.meta.url);
  82 | const __dirname = dirname(__filename);
  83 | const packageJson = JSON.parse(
  84 |   readFileSync(join(__dirname, "..", "package.json"), "utf-8"),
  85 | );
  86 | 
  87 | // Parse allowed roots from command line arguments
  88 | const allowedRoots: string[] = [];
  89 | process.argv.forEach((arg, index) => {
  90 |   if (arg === "--root" && process.argv[index + 1]) {
  91 |     const rootPath = process.argv[index + 1];
  92 |     // Resolve to absolute path and expand ~ for home directory
  93 |     const expandedPath = rootPath.startsWith("~")
  94 |       ? join(
  95 |           process.env.HOME || process.env.USERPROFILE || "",
  96 |           rootPath.slice(1),
  97 |         )
  98 |       : rootPath;
  99 |     allowedRoots.push(path.resolve(expandedPath));
 100 |   }
 101 | });
 102 | 
 103 | // If no roots specified, allow current working directory by default
 104 | if (allowedRoots.length === 0) {
 105 |   allowedRoots.push(process.cwd());
 106 | }
 107 | 
 108 | const server = new Server(
 109 |   {
 110 |     name: "documcp",
 111 |     version: packageJson.version,
 112 |   },
 113 |   {
 114 |     capabilities: {
 115 |       tools: {},
 116 |       prompts: {
 117 |         listChanged: true,
 118 |       },
 119 |       resources: {
 120 |         subscribe: true,
 121 |         listChanged: true,
 122 |       },
 123 |       roots: {
 124 |         listChanged: true,
 125 |       },
 126 |     },
 127 |   },
 128 | );
 129 | 
 130 | // Tool definitions following ADR-006
 131 | const TOOLS = [
 132 |   {
 133 |     name: "analyze_repository",
 134 |     description:
 135 |       "Analyze repository structure, dependencies, and documentation needs",
 136 |     inputSchema: z.object({
 137 |       path: z.string().describe("Path to the repository to analyze"),
 138 |       depth: z
 139 |         .enum(["quick", "standard", "deep"])
 140 |         .optional()
 141 |         .default("standard"),
 142 |     }),
 143 |   },
 144 |   {
 145 |     name: "recommend_ssg",
 146 |     description:
 147 |       "Recommend the best static site generator based on project analysis and user preferences",
 148 |     inputSchema: z.object({
 149 |       analysisId: z.string().describe("ID from previous repository analysis"),
 150 |       userId: z
 151 |         .string()
 152 |         .optional()
 153 |         .default("default")
 154 |         .describe(
 155 |           "User ID for personalized recommendations based on usage history",
 156 |         ),
 157 |       preferences: z
 158 |         .object({
 159 |           priority: z
 160 |             .enum(["simplicity", "features", "performance"])
 161 |             .optional(),
 162 |           ecosystem: z
 163 |             .enum(["javascript", "python", "ruby", "go", "any"])
 164 |             .optional(),
 165 |         })
 166 |         .optional(),
 167 |     }),
 168 |   },
 169 |   {
 170 |     name: "generate_config",
 171 |     description:
 172 |       "Generate configuration files for the selected static site generator",
 173 |     inputSchema: z.object({
 174 |       ssg: z.enum(["jekyll", "hugo", "docusaurus", "mkdocs", "eleventy"]),
 175 |       projectName: z.string(),
 176 |       projectDescription: z.string().optional(),
 177 |       outputPath: z.string().describe("Where to generate config files"),
 178 |     }),
 179 |   },
 180 |   {
 181 |     name: "setup_structure",
 182 |     description: "Create Diataxis-compliant documentation structure",
 183 |     inputSchema: z.object({
 184 |       path: z.string().describe("Root path for documentation"),
 185 |       ssg: z.enum(["jekyll", "hugo", "docusaurus", "mkdocs", "eleventy"]),
 186 |       includeExamples: z.boolean().optional().default(true),
 187 |     }),
 188 |   },
 189 |   {
 190 |     name: "setup_playwright_tests",
 191 |     description:
 192 |       "Generate Playwright E2E test setup for documentation site (containers + CI/CD)",
 193 |     inputSchema: z.object({
 194 |       repositoryPath: z.string().describe("Path to documentation repository"),
 195 |       ssg: z.enum(["jekyll", "hugo", "docusaurus", "mkdocs", "eleventy"]),
 196 |       projectName: z.string().describe("Project name for tests"),
 197 |       mainBranch: z.string().optional().default("main"),
 198 |       includeAccessibilityTests: z.boolean().optional().default(true),
 199 |       includeDockerfile: z.boolean().optional().default(true),
 200 |       includeGitHubActions: z.boolean().optional().default(true),
 201 |     }),
 202 |   },
 203 |   {
 204 |     name: "deploy_pages",
 205 |     description:
 206 |       "Set up GitHub Pages deployment workflow with deployment tracking and preference learning",
 207 |     inputSchema: z.object({
 208 |       repository: z.string().describe("Repository path or URL"),
 209 |       ssg: z.enum(["jekyll", "hugo", "docusaurus", "mkdocs", "eleventy"]),
 210 |       branch: z.string().optional().default("gh-pages"),
 211 |       customDomain: z.string().optional(),
 212 |       projectPath: z
 213 |         .string()
 214 |         .optional()
 215 |         .describe("Local path to the project for tracking"),
 216 |       projectName: z.string().optional().describe("Project name for tracking"),
 217 |       analysisId: z
 218 |         .string()
 219 |         .optional()
 220 |         .describe("ID from repository analysis for linking"),
 221 |       userId: z
 222 |         .string()
 223 |         .optional()
 224 |         .default("default")
 225 |         .describe("User ID for preference tracking"),
 226 |     }),
 227 |   },
 228 |   {
 229 |     name: "verify_deployment",
 230 |     description: "Verify and troubleshoot GitHub Pages deployment",
 231 |     inputSchema: z.object({
 232 |       repository: z.string().describe("Repository path or URL"),
 233 |       url: z.string().optional().describe("Expected deployment URL"),
 234 |     }),
 235 |   },
 236 |   {
 237 |     name: "populate_diataxis_content",
 238 |     description:
 239 |       "Intelligently populate Diataxis documentation with project-specific content",
 240 |     inputSchema: z.object({
 241 |       analysisId: z
 242 |         .string()
 243 |         .describe("Repository analysis ID from analyze_repository tool"),
 244 |       docsPath: z.string().describe("Path to documentation directory"),
 245 |       populationLevel: z
 246 |         .enum(["basic", "comprehensive", "intelligent"])
 247 |         .optional()
 248 |         .default("comprehensive"),
 249 |       includeProjectSpecific: z.boolean().optional().default(true),
 250 |       preserveExisting: z.boolean().optional().default(true),
 251 |       technologyFocus: z
 252 |         .array(z.string())
 253 |         .optional()
 254 |         .describe("Specific technologies to emphasize"),
 255 |     }),
 256 |   },
 257 |   {
 258 |     name: "update_existing_documentation",
 259 |     description:
 260 |       "Intelligently analyze and update existing documentation using memory insights and code comparison",
 261 |     inputSchema: z.object({
 262 |       analysisId: z
 263 |         .string()
 264 |         .describe("Repository analysis ID from analyze_repository tool"),
 265 |       docsPath: z.string().describe("Path to existing documentation directory"),
 266 |       compareMode: z
 267 |         .enum(["comprehensive", "gap-detection", "accuracy-check"])
 268 |         .optional()
 269 |         .default("comprehensive")
 270 |         .describe("Mode of comparison between code and documentation"),
 271 |       updateStrategy: z
 272 |         .enum(["conservative", "moderate", "aggressive"])
 273 |         .optional()
 274 |         .default("moderate")
 275 |         .describe("How aggressively to suggest updates"),
 276 |       preserveStyle: z
 277 |         .boolean()
 278 |         .optional()
 279 |         .default(true)
 280 |         .describe("Preserve existing documentation style and formatting"),
 281 |       focusAreas: z
 282 |         .array(z.string())
 283 |         .optional()
 284 |         .describe(
 285 |           'Specific areas to focus updates on (e.g., "dependencies", "scripts", "api")',
 286 |         ),
 287 |     }),
 288 |   },
 289 |   {
 290 |     name: "validate_diataxis_content",
 291 |     description:
 292 |       "Validate the accuracy, completeness, and compliance of generated Diataxis documentation",
 293 |     inputSchema: z.object({
 294 |       contentPath: z
 295 |         .string()
 296 |         .describe("Path to the documentation directory to validate"),
 297 |       analysisId: z
 298 |         .string()
 299 |         .optional()
 300 |         .describe(
 301 |           "Optional repository analysis ID for context-aware validation",
 302 |         ),
 303 |       validationType: z
 304 |         .enum(["accuracy", "completeness", "compliance", "all"])
 305 |         .optional()
 306 |         .default("all")
 307 |         .describe(
 308 |           "Type of validation: accuracy, completeness, compliance, or all",
 309 |         ),
 310 |       includeCodeValidation: z
 311 |         .boolean()
 312 |         .optional()
 313 |         .default(true)
 314 |         .describe("Whether to validate code examples"),
 315 |       confidence: z
 316 |         .enum(["strict", "moderate", "permissive"])
 317 |         .optional()
 318 |         .default("moderate")
 319 |         .describe(
 320 |           "Validation confidence level: strict, moderate, or permissive",
 321 |         ),
 322 |     }),
 323 |   },
 324 |   {
 325 |     name: "validate_content",
 326 |     description:
 327 |       "Validate general content quality: broken links, code syntax, references, and basic accuracy",
 328 |     inputSchema: z.object({
 329 |       contentPath: z
 330 |         .string()
 331 |         .describe("Path to the content directory to validate"),
 332 |       validationType: z
 333 |         .string()
 334 |         .optional()
 335 |         .default("all")
 336 |         .describe("Type of validation: links, code, references, or all"),
 337 |       includeCodeValidation: z
 338 |         .boolean()
 339 |         .optional()
 340 |         .default(true)
 341 |         .describe("Whether to validate code blocks"),
 342 |       followExternalLinks: z
 343 |         .boolean()
 344 |         .optional()
 345 |         .default(false)
 346 |         .describe("Whether to validate external URLs (slower)"),
 347 |     }),
 348 |   },
 349 |   {
 350 |     name: "detect_documentation_gaps",
 351 |     description:
 352 |       "Analyze repository and existing documentation to identify missing content and gaps",
 353 |     inputSchema: z.object({
 354 |       repositoryPath: z.string().describe("Path to the repository to analyze"),
 355 |       documentationPath: z
 356 |         .string()
 357 |         .optional()
 358 |         .describe("Path to existing documentation (if any)"),
 359 |       analysisId: z
 360 |         .string()
 361 |         .optional()
 362 |         .describe("Optional existing analysis ID to reuse"),
 363 |       depth: z
 364 |         .enum(["quick", "standard", "comprehensive"])
 365 |         .optional()
 366 |         .default("standard"),
 367 |     }),
 368 |   },
 369 |   {
 370 |     name: "test_local_deployment",
 371 |     description:
 372 |       "Test documentation build and local server before deploying to GitHub Pages",
 373 |     inputSchema: z.object({
 374 |       repositoryPath: z.string().describe("Path to the repository"),
 375 |       ssg: z.enum(["jekyll", "hugo", "docusaurus", "mkdocs", "eleventy"]),
 376 |       port: z
 377 |         .number()
 378 |         .optional()
 379 |         .default(3000)
 380 |         .describe("Port for local server"),
 381 |       timeout: z
 382 |         .number()
 383 |         .optional()
 384 |         .default(60)
 385 |         .describe("Timeout in seconds for build process"),
 386 |       skipBuild: z
 387 |         .boolean()
 388 |         .optional()
 389 |         .default(false)
 390 |         .describe("Skip build step and only start server"),
 391 |     }),
 392 |   },
 393 |   {
 394 |     name: "evaluate_readme_health",
 395 |     description:
 396 |       "Evaluate README files for community health, accessibility, and onboarding effectiveness",
 397 |     inputSchema: z.object({
 398 |       readme_path: z.string().describe("Path to the README file to evaluate"),
 399 |       project_type: z
 400 |         .enum([
 401 |           "community_library",
 402 |           "enterprise_tool",
 403 |           "personal_project",
 404 |           "documentation",
 405 |         ])
 406 |         .optional()
 407 |         .default("community_library")
 408 |         .describe("Type of project for tailored evaluation"),
 409 |       repository_path: z
 410 |         .string()
 411 |         .optional()
 412 |         .describe("Optional path to repository for additional context"),
 413 |     }),
 414 |   },
 415 |   {
 416 |     name: "readme_best_practices",
 417 |     description:
 418 |       "Analyze README files against best practices checklist and generate templates for improvement",
 419 |     inputSchema: z.object({
 420 |       readme_path: z.string().describe("Path to the README file to analyze"),
 421 |       project_type: z
 422 |         .enum(["library", "application", "tool", "documentation", "framework"])
 423 |         .optional()
 424 |         .default("library")
 425 |         .describe("Type of project for tailored analysis"),
 426 |       generate_template: z
 427 |         .boolean()
 428 |         .optional()
 429 |         .default(false)
 430 |         .describe("Generate README templates and community files"),
 431 |       output_directory: z
 432 |         .string()
 433 |         .optional()
 434 |         .describe("Directory to write generated templates and community files"),
 435 |       include_community_files: z
 436 |         .boolean()
 437 |         .optional()
 438 |         .default(true)
 439 |         .describe(
 440 |           "Generate community health files (CONTRIBUTING.md, CODE_OF_CONDUCT.md, etc.)",
 441 |         ),
 442 |       target_audience: z
 443 |         .enum(["beginner", "intermediate", "advanced", "mixed"])
 444 |         .optional()
 445 |         .default("mixed")
 446 |         .describe("Target audience for recommendations"),
 447 |     }),
 448 |   },
 449 |   {
 450 |     name: "check_documentation_links",
 451 |     description:
 452 |       "Comprehensive link checking for documentation deployment with external, internal, and anchor link validation",
 453 |     inputSchema: z.object({
 454 |       documentation_path: z
 455 |         .string()
 456 |         .optional()
 457 |         .default("./docs")
 458 |         .describe("Path to the documentation directory to check"),
 459 |       check_external_links: z
 460 |         .boolean()
 461 |         .optional()
 462 |         .default(true)
 463 |         .describe("Validate external URLs (slower but comprehensive)"),
 464 |       check_internal_links: z
 465 |         .boolean()
 466 |         .optional()
 467 |         .default(true)
 468 |         .describe("Validate internal file references"),
 469 |       check_anchor_links: z
 470 |         .boolean()
 471 |         .optional()
 472 |         .default(true)
 473 |         .describe("Validate anchor links within documents"),
 474 |       timeout_ms: z
 475 |         .number()
 476 |         .min(1000)
 477 |         .max(30000)
 478 |         .optional()
 479 |         .default(5000)
 480 |         .describe("Timeout for external link requests in milliseconds"),
 481 |       max_concurrent_checks: z
 482 |         .number()
 483 |         .min(1)
 484 |         .max(20)
 485 |         .optional()
 486 |         .default(5)
 487 |         .describe("Maximum concurrent link checks"),
 488 |       allowed_domains: z
 489 |         .array(z.string())
 490 |         .optional()
 491 |         .default([])
 492 |         .describe(
 493 |           "Whitelist of allowed external domains (empty = all allowed)",
 494 |         ),
 495 |       ignore_patterns: z
 496 |         .array(z.string())
 497 |         .optional()
 498 |         .default([])
 499 |         .describe("URL patterns to ignore during checking"),
 500 |       fail_on_broken_links: z
 501 |         .boolean()
 502 |         .optional()
 503 |         .default(false)
 504 |         .describe("Fail the check if broken links are found"),
 505 |       output_format: z
 506 |         .enum(["summary", "detailed", "json"])
 507 |         .optional()
 508 |         .default("detailed")
 509 |         .describe("Output format for results"),
 510 |     }),
 511 |   },
 512 |   {
 513 |     name: "generate_readme_template",
 514 |     description:
 515 |       "Generate standardized README templates for different project types with best practices",
 516 |     inputSchema: z.object({
 517 |       projectName: z.string().min(1).describe("Name of the project"),
 518 |       description: z
 519 |         .string()
 520 |         .min(1)
 521 |         .describe("Brief description of what the project does"),
 522 |       templateType: z
 523 |         .enum(["library", "application", "cli-tool", "api", "documentation"])
 524 |         .describe("Type of project template to generate"),
 525 |       author: z
 526 |         .string()
 527 |         .optional()
 528 |         .describe("Project author/organization name"),
 529 |       license: z.string().optional().default("MIT").describe("Project license"),
 530 |       includeScreenshots: z
 531 |         .boolean()
 532 |         .optional()
 533 |         .default(false)
 534 |         .describe("Include screenshot placeholders for applications"),
 535 |       includeBadges: z
 536 |         .boolean()
 537 |         .optional()
 538 |         .default(true)
 539 |         .describe("Include status badges"),
 540 |       includeContributing: z
 541 |         .boolean()
 542 |         .optional()
 543 |         .default(true)
 544 |         .describe("Include contributing section"),
 545 |       outputPath: z
 546 |         .string()
 547 |         .optional()
 548 |         .describe("Path to write the generated README.md file"),
 549 |     }),
 550 |   },
 551 |   {
 552 |     name: "validate_readme_checklist",
 553 |     description:
 554 |       "Validate README files against community best practices checklist with detailed scoring",
 555 |     inputSchema: z.object({
 556 |       readmePath: z
 557 |         .string()
 558 |         .min(1)
 559 |         .describe("Path to the README file to validate"),
 560 |       projectPath: z
 561 |         .string()
 562 |         .optional()
 563 |         .describe("Path to project directory for additional context"),
 564 |       strict: z
 565 |         .boolean()
 566 |         .optional()
 567 |         .default(false)
 568 |         .describe("Use strict validation rules"),
 569 |       outputFormat: z
 570 |         .enum(["json", "markdown", "console"])
 571 |         .optional()
 572 |         .default("console")
 573 |         .describe("Output format for the validation report"),
 574 |     }),
 575 |   },
 576 |   {
 577 |     name: "analyze_readme",
 578 |     description:
 579 |       "Comprehensive README analysis with length assessment, structure evaluation, and optimization opportunities",
 580 |     inputSchema: z.object({
 581 |       project_path: z
 582 |         .string()
 583 |         .min(1)
 584 |         .describe("Path to the project directory containing README"),
 585 |       target_audience: z
 586 |         .enum([
 587 |           "community_contributors",
 588 |           "enterprise_users",
 589 |           "developers",
 590 |           "general",
 591 |         ])
 592 |         .optional()
 593 |         .default("community_contributors")
 594 |         .describe("Target audience for analysis"),
 595 |       optimization_level: z
 596 |         .enum(["light", "moderate", "aggressive"])
 597 |         .optional()
 598 |         .default("moderate")
 599 |         .describe("Level of optimization suggestions"),
 600 |       max_length_target: z
 601 |         .number()
 602 |         .min(50)
 603 |         .max(1000)
 604 |         .optional()
 605 |         .default(300)
 606 |         .describe("Target maximum length in lines"),
 607 |     }),
 608 |   },
 609 |   {
 610 |     name: "optimize_readme",
 611 |     description:
 612 |       "Optimize README content by restructuring, condensing, and extracting detailed sections to separate documentation",
 613 |     inputSchema: z.object({
 614 |       readme_path: z
 615 |         .string()
 616 |         .min(1)
 617 |         .describe("Path to the README file to optimize"),
 618 |       strategy: z
 619 |         .enum([
 620 |           "community_focused",
 621 |           "enterprise_focused",
 622 |           "developer_focused",
 623 |           "general",
 624 |         ])
 625 |         .optional()
 626 |         .default("community_focused")
 627 |         .describe("Optimization strategy"),
 628 |       max_length: z
 629 |         .number()
 630 |         .min(50)
 631 |         .max(1000)
 632 |         .optional()
 633 |         .default(300)
 634 |         .describe("Target maximum length in lines"),
 635 |       include_tldr: z
 636 |         .boolean()
 637 |         .optional()
 638 |         .default(true)
 639 |         .describe("Generate and include TL;DR section"),
 640 |       preserve_existing: z
 641 |         .boolean()
 642 |         .optional()
 643 |         .default(true)
 644 |         .describe("Preserve existing content structure where possible"),
 645 |       output_path: z
 646 |         .string()
 647 |         .optional()
 648 |         .describe(
 649 |           "Path to write optimized README (if not specified, returns content only)",
 650 |         ),
 651 |       create_docs_directory: z
 652 |         .boolean()
 653 |         .optional()
 654 |         .default(true)
 655 |         .describe("Create docs/ directory for extracted content"),
 656 |     }),
 657 |   },
 658 |   {
 659 |     name: "manage_preferences",
 660 |     description:
 661 |       "Manage user preferences for documentation generation and SSG recommendations",
 662 |     inputSchema: z.object({
 663 |       action: z
 664 |         .enum(["get", "update", "reset", "export", "import", "recommendations"])
 665 |         .describe("Action to perform on preferences"),
 666 |       userId: z
 667 |         .string()
 668 |         .optional()
 669 |         .default("default")
 670 |         .describe("User ID for multi-user setups"),
 671 |       preferences: z
 672 |         .object({
 673 |           preferredSSGs: z
 674 |             .array(z.string())
 675 |             .optional()
 676 |             .describe("List of preferred static site generators"),
 677 |           documentationStyle: z
 678 |             .enum(["minimal", "comprehensive", "tutorial-heavy"])
 679 |             .optional()
 680 |             .describe("Preferred documentation style"),
 681 |           expertiseLevel: z
 682 |             .enum(["beginner", "intermediate", "advanced"])
 683 |             .optional()
 684 |             .describe("User's technical expertise level"),
 685 |           preferredTechnologies: z
 686 |             .array(z.string())
 687 |             .optional()
 688 |             .describe("Preferred technologies and frameworks"),
 689 |           preferredDiataxisCategories: z
 690 |             .array(z.enum(["tutorials", "how-to", "reference", "explanation"]))
 691 |             .optional()
 692 |             .describe("Preferred Diataxis documentation categories"),
 693 |           autoApplyPreferences: z
 694 |             .boolean()
 695 |             .optional()
 696 |             .describe("Automatically apply preferences to recommendations"),
 697 |         })
 698 |         .optional()
 699 |         .describe("Preference updates (for update action)"),
 700 |       json: z.string().optional().describe("JSON string for import action"),
 701 |     }),
 702 |   },
 703 |   {
 704 |     name: "analyze_deployments",
 705 |     description:
 706 |       "Analyze deployment patterns and generate insights from historical deployment data",
 707 |     inputSchema: z.object({
 708 |       analysisType: z
 709 |         .enum(["full_report", "ssg_stats", "compare", "health", "trends"])
 710 |         .optional()
 711 |         .default("full_report")
 712 |         .describe(
 713 |           "Type of analysis: full_report (comprehensive), ssg_stats (per-SSG), compare (compare SSGs), health (deployment health score), trends (temporal analysis)",
 714 |         ),
 715 |       ssg: z.string().optional().describe("SSG name for ssg_stats analysis"),
 716 |       ssgs: z
 717 |         .array(z.string())
 718 |         .optional()
 719 |         .describe("Array of SSG names for comparison"),
 720 |       periodDays: z
 721 |         .number()
 722 |         .optional()
 723 |         .default(30)
 724 |         .describe("Period in days for trend analysis"),
 725 |     }),
 726 |   },
 727 |   {
 728 |     name: "read_directory",
 729 |     description:
 730 |       "List files and directories within allowed roots. Use this to discover files without requiring full absolute paths from the user.",
 731 |     inputSchema: z.object({
 732 |       path: z
 733 |         .string()
 734 |         .describe(
 735 |           "Path to directory (relative to root or absolute within root)",
 736 |         ),
 737 |     }),
 738 |   },
 739 |   // Phase 3: Code-to-Documentation Synchronization
 740 |   {
 741 |     name: "sync_code_to_docs",
 742 |     description:
 743 |       "Automatically synchronize documentation with code changes using AST-based drift detection (Phase 3)",
 744 |     inputSchema: z.object({
 745 |       projectPath: z.string().describe("Path to the project root directory"),
 746 |       docsPath: z.string().describe("Path to the documentation directory"),
 747 |       mode: z
 748 |         .enum(["detect", "preview", "apply", "auto"])
 749 |         .default("detect")
 750 |         .describe(
 751 |           "Sync mode: detect=analyze only, preview=show changes, apply=apply safe changes, auto=apply all",
 752 |         ),
 753 |       autoApplyThreshold: z
 754 |         .number()
 755 |         .min(0)
 756 |         .max(1)
 757 |         .default(0.8)
 758 |         .describe(
 759 |           "Confidence threshold (0-1) for automatic application of changes",
 760 |         ),
 761 |       createSnapshot: z
 762 |         .boolean()
 763 |         .default(true)
 764 |         .describe("Create a snapshot before making changes (recommended)"),
 765 |     }),
 766 |   },
 767 |   {
 768 |     name: "generate_contextual_content",
 769 |     description:
 770 |       "Generate context-aware documentation using AST analysis and knowledge graph insights (Phase 3)",
 771 |     inputSchema: z.object({
 772 |       filePath: z.string().describe("Path to the source code file to document"),
 773 |       documentationType: z
 774 |         .enum(["tutorial", "how-to", "reference", "explanation", "all"])
 775 |         .default("reference")
 776 |         .describe("Type of Diataxis documentation to generate"),
 777 |       includeExamples: z
 778 |         .boolean()
 779 |         .default(true)
 780 |         .describe("Include code examples in generated documentation"),
 781 |       style: z
 782 |         .enum(["concise", "detailed", "verbose"])
 783 |         .default("detailed")
 784 |         .describe("Documentation detail level"),
 785 |       outputFormat: z
 786 |         .enum(["markdown", "mdx", "html"])
 787 |         .default("markdown")
 788 |         .describe("Output format for generated content"),
 789 |     }),
 790 |   },
 791 |   // Documentation Freshness Tracking
 792 |   {
 793 |     name: "track_documentation_freshness",
 794 |     description:
 795 |       "Scan documentation directory for staleness markers and identify files needing updates based on configurable time thresholds (minutes, hours, days)",
 796 |     inputSchema: z.object({
 797 |       docsPath: z.string().describe("Path to documentation directory"),
 798 |       projectPath: z
 799 |         .string()
 800 |         .optional()
 801 |         .describe("Path to project root (for knowledge graph tracking)"),
 802 |       warningThreshold: z
 803 |         .object({
 804 |           value: z.number().positive(),
 805 |           unit: z.enum(["minutes", "hours", "days"]),
 806 |         })
 807 |         .optional()
 808 |         .describe("Warning threshold (yellow flag)"),
 809 |       staleThreshold: z
 810 |         .object({
 811 |           value: z.number().positive(),
 812 |           unit: z.enum(["minutes", "hours", "days"]),
 813 |         })
 814 |         .optional()
 815 |         .describe("Stale threshold (orange flag)"),
 816 |       criticalThreshold: z
 817 |         .object({
 818 |           value: z.number().positive(),
 819 |           unit: z.enum(["minutes", "hours", "days"]),
 820 |         })
 821 |         .optional()
 822 |         .describe("Critical threshold (red flag)"),
 823 |       preset: z
 824 |         .enum([
 825 |           "realtime",
 826 |           "active",
 827 |           "recent",
 828 |           "weekly",
 829 |           "monthly",
 830 |           "quarterly",
 831 |         ])
 832 |         .optional()
 833 |         .describe("Use predefined threshold preset"),
 834 |       includeFileList: z
 835 |         .boolean()
 836 |         .optional()
 837 |         .default(true)
 838 |         .describe("Include detailed file list in response"),
 839 |       sortBy: z
 840 |         .enum(["age", "path", "staleness"])
 841 |         .optional()
 842 |         .default("staleness")
 843 |         .describe("Sort order for file list"),
 844 |       storeInKG: z
 845 |         .boolean()
 846 |         .optional()
 847 |         .default(true)
 848 |         .describe(
 849 |           "Store tracking event in knowledge graph for historical analysis",
 850 |         ),
 851 |     }),
 852 |   },
 853 |   {
 854 |     name: "validate_documentation_freshness",
 855 |     description:
 856 |       "Validate documentation freshness, initialize metadata for files without it, and update timestamps based on code changes",
 857 |     inputSchema: z.object({
 858 |       docsPath: z.string().describe("Path to documentation directory"),
 859 |       projectPath: z
 860 |         .string()
 861 |         .describe("Path to project root (for git integration)"),
 862 |       initializeMissing: z
 863 |         .boolean()
 864 |         .optional()
 865 |         .default(true)
 866 |         .describe("Initialize metadata for files without it"),
 867 |       updateExisting: z
 868 |         .boolean()
 869 |         .optional()
 870 |         .default(false)
 871 |         .describe("Update last_validated timestamp for all files"),
 872 |       updateFrequency: z
 873 |         .enum([
 874 |           "realtime",
 875 |           "active",
 876 |           "recent",
 877 |           "weekly",
 878 |           "monthly",
 879 |           "quarterly",
 880 |         ])
 881 |         .optional()
 882 |         .default("monthly")
 883 |         .describe("Default update frequency for new metadata"),
 884 |       validateAgainstGit: z
 885 |         .boolean()
 886 |         .optional()
 887 |         .default(true)
 888 |         .describe("Validate against current git commit"),
 889 |     }),
 890 |   },
 891 |   {
 892 |     name: "manage_sitemap",
 893 |     description:
 894 |       "Generate, validate, and manage sitemap.xml as the source of truth for documentation links. Sitemap.xml is used for SEO, search engine submission, and deployment tracking.",
 895 |     inputSchema: ManageSitemapInputSchema,
 896 |   },
 897 |   {
 898 |     name: "generate_llm_context",
 899 |     description:
 900 |       "Generate a comprehensive LLM context reference file documenting all tools, memory system, and workflows for easy @ reference",
 901 |     inputSchema: GenerateLLMContextInputSchema,
 902 |   },
 903 |   // Memory system tools
 904 |   ...memoryTools.map((tool) => ({
 905 |     ...tool,
 906 |     inputSchema: z.object(
 907 |       Object.entries(tool.inputSchema.properties || {}).reduce(
 908 |         (acc: any, [key, value]: [string, any]) => {
 909 |           if (value.type === "string") {
 910 |             acc[key] = value.enum ? z.enum(value.enum) : z.string();
 911 |           } else if (value.type === "number") {
 912 |             acc[key] = z.number();
 913 |           } else if (value.type === "boolean") {
 914 |             acc[key] = z.boolean();
 915 |           } else if (value.type === "object") {
 916 |             acc[key] = z.object({});
 917 |           }
 918 |           if (value.description) {
 919 |             acc[key] = acc[key].describe(value.description);
 920 |           }
 921 |           if (!tool.inputSchema.required?.includes(key)) {
 922 |             acc[key] = acc[key].optional();
 923 |           }
 924 |           if (value.default !== undefined) {
 925 |             acc[key] = acc[key].default(value.default);
 926 |           }
 927 |           return acc;
 928 |         },
 929 |         {},
 930 |       ),
 931 |     ),
 932 |   })),
 933 | ];
 934 | 
 935 | // Export TOOLS for use in generate_llm_context tool
 936 | export { TOOLS };
 937 | 
 938 | // Set tool definitions for generate_llm_context tool
 939 | setToolDefinitions(TOOLS);
 940 | 
 941 | // Native MCP Prompts for technical writing assistance
 942 | const PROMPTS = [
 943 |   {
 944 |     name: "tutorial-writer",
 945 |     description:
 946 |       "Generate learning-oriented tutorial content following Diataxis principles",
 947 |     arguments: [
 948 |       {
 949 |         name: "project_path",
 950 |         description:
 951 |           "Path to the project directory (used to analyze project context)",
 952 |         required: true,
 953 |       },
 954 |       {
 955 |         name: "target_audience",
 956 |         description:
 957 |           "Target audience for the tutorial (default: 'beginners'). Options: 'beginners', 'intermediate', 'advanced'",
 958 |         required: false,
 959 |       },
 960 |       {
 961 |         name: "learning_goal",
 962 |         description:
 963 |           "What users should learn (default: 'get started with the project'). Examples: 'deploy first app', 'understand core concepts'",
 964 |         required: false,
 965 |       },
 966 |     ],
 967 |   },
 968 |   {
 969 |     name: "howto-guide-writer",
 970 |     description:
 971 |       "Generate problem-oriented how-to guide content following Diataxis principles",
 972 |     arguments: [
 973 |       {
 974 |         name: "project_path",
 975 |         description:
 976 |           "Path to the project directory (used to analyze project context)",
 977 |         required: true,
 978 |       },
 979 |       {
 980 |         name: "problem",
 981 |         description:
 982 |           "Problem to solve (default: 'common development task'). Example: 'deploy to production', 'add authentication'",
 983 |         required: false,
 984 |       },
 985 |       {
 986 |         name: "user_experience",
 987 |         description:
 988 |           "User experience level (default: 'intermediate'). Options: 'beginner', 'intermediate', 'advanced'",
 989 |         required: false,
 990 |       },
 991 |     ],
 992 |   },
 993 |   {
 994 |     name: "reference-writer",
 995 |     description:
 996 |       "Generate information-oriented reference documentation following Diataxis principles",
 997 |     arguments: [
 998 |       {
 999 |         name: "project_path",
1000 |         description:
1001 |           "Path to the project directory (used to analyze project context)",
1002 |         required: true,
1003 |       },
1004 |       {
1005 |         name: "reference_type",
1006 |         description:
1007 |           "Type of reference (default: 'API'). Options: 'API', 'CLI', 'Configuration', 'Architecture'",
1008 |         required: false,
1009 |       },
1010 |       {
1011 |         name: "completeness",
1012 |         description:
1013 |           "Level of completeness required (default: 'comprehensive'). Options: 'basic', 'comprehensive', 'exhaustive'",
1014 |         required: false,
1015 |       },
1016 |     ],
1017 |   },
1018 |   {
1019 |     name: "explanation-writer",
1020 |     description:
1021 |       "Generate understanding-oriented explanation content following Diataxis principles",
1022 |     arguments: [
1023 |       {
1024 |         name: "project_path",
1025 |         description:
1026 |           "Path to the project directory (used to analyze project context)",
1027 |         required: true,
1028 |       },
1029 |       {
1030 |         name: "concept",
1031 |         description:
1032 |           "Concept to explain (default: 'system architecture'). Examples: 'data flow', 'design patterns', 'security model'",
1033 |         required: false,
1034 |       },
1035 |       {
1036 |         name: "depth",
1037 |         description:
1038 |           "Depth of explanation (default: 'detailed'). Options: 'overview', 'detailed', 'deep-dive'",
1039 |         required: false,
1040 |       },
1041 |     ],
1042 |   },
1043 |   {
1044 |     name: "diataxis-organizer",
1045 |     description:
1046 |       "Organize existing documentation using Diataxis framework principles",
1047 |     arguments: [
1048 |       {
1049 |         name: "project_path",
1050 |         description:
1051 |           "Path to the project directory (used to analyze project context)",
1052 |         required: true,
1053 |       },
1054 |       {
1055 |         name: "current_docs",
1056 |         description:
1057 |           "Description of current documentation (default: 'mixed documentation'). Example: 'single README with everything', 'scattered wiki pages'",
1058 |         required: false,
1059 |       },
1060 |       {
1061 |         name: "priority",
1062 |         description:
1063 |           "Organization priority (default: 'user needs'). Options: 'user needs', 'completeness', 'maintainability'",
1064 |         required: false,
1065 |       },
1066 |     ],
1067 |   },
1068 |   {
1069 |     name: "readme-optimizer",
1070 |     description: "Optimize README content using Diataxis-aware principles",
1071 |     arguments: [
1072 |       {
1073 |         name: "project_path",
1074 |         description:
1075 |           "Path to the project directory (used to analyze README and project context)",
1076 |         required: true,
1077 |       },
1078 |       {
1079 |         name: "optimization_focus",
1080 |         description:
1081 |           "Focus area for optimization (default: 'general'). Options: 'length', 'clarity', 'structure', 'onboarding'",
1082 |         required: false,
1083 |       },
1084 |     ],
1085 |   },
1086 |   // Guided workflow prompts (ADR-007)
1087 |   {
1088 |     name: "analyze-and-recommend",
1089 |     description: "Complete repository analysis and SSG recommendation workflow",
1090 |     arguments: [
1091 |       {
1092 |         name: "project_path",
1093 |         description: "Path to the project directory (used for analysis)",
1094 |         required: true,
1095 |       },
1096 |       {
1097 |         name: "analysis_depth",
1098 |         description:
1099 |           "Analysis depth (default: 'standard'). Options: 'quick' (basic scan), 'standard' (comprehensive), 'deep' (detailed with dependencies)",
1100 |         required: false,
1101 |       },
1102 |       {
1103 |         name: "preferences",
1104 |         description:
1105 |           "SSG preferences as text (default: 'balanced approach'). Examples: 'prefer JavaScript ecosystem', 'prioritize simplicity', 'need fast builds'",
1106 |         required: false,
1107 |       },
1108 |     ],
1109 |   },
1110 |   {
1111 |     name: "setup-documentation",
1112 |     description:
1113 |       "Create comprehensive documentation structure with best practices",
1114 |     arguments: [
1115 |       {
1116 |         name: "project_path",
1117 |         description:
1118 |           "Path to the project directory (where docs will be created)",
1119 |         required: true,
1120 |       },
1121 |       {
1122 |         name: "ssg_type",
1123 |         description:
1124 |           "Static site generator type (default: 'recommended based on analysis'). Options: 'jekyll', 'hugo', 'docusaurus', 'mkdocs', 'eleventy'",
1125 |         required: false,
1126 |       },
1127 |       {
1128 |         name: "include_examples",
1129 |         description:
1130 |           "Include example content (default: 'true'). Set to 'false' for templates only, 'true' for populated examples",
1131 |         required: false,
1132 |       },
1133 |     ],
1134 |   },
1135 |   {
1136 |     name: "troubleshoot-deployment",
1137 |     description: "Diagnose and fix GitHub Pages deployment issues",
1138 |     arguments: [
1139 |       {
1140 |         name: "repository",
1141 |         description:
1142 |           "Repository path or URL (GitHub repository to troubleshoot)",
1143 |         required: true,
1144 |       },
1145 |       {
1146 |         name: "deployment_url",
1147 |         description:
1148 |           "Expected deployment URL (default: derived from repository). Example: 'https://username.github.io/repo'",
1149 |         required: false,
1150 |       },
1151 |       {
1152 |         name: "issue_description",
1153 |         description:
1154 |           "Description of the issue (default: 'deployment not working'). Examples: 'builds fail', '404 errors', 'outdated content'",
1155 |         required: false,
1156 |       },
1157 |     ],
1158 |   },
1159 |   {
1160 |     name: "maintain-documentation-freshness",
1161 |     description:
1162 |       "Track and maintain documentation freshness with automated staleness detection",
1163 |     arguments: [
1164 |       {
1165 |         name: "project_path",
1166 |         description:
1167 |           "Path to the project directory (used for knowledge graph tracking)",
1168 |         required: true,
1169 |       },
1170 |       {
1171 |         name: "docs_path",
1172 |         description:
1173 |           "Path to documentation directory (default: derived from project). Example: './docs', './documentation'",
1174 |         required: false,
1175 |       },
1176 |       {
1177 |         name: "freshness_preset",
1178 |         description:
1179 |           "Staleness threshold preset (default: 'monthly'). Options: 'realtime' (minutes), 'active' (hours), 'recent' (days), 'weekly' (7 days), 'monthly' (30 days), 'quarterly' (90 days)",
1180 |         required: false,
1181 |       },
1182 |       {
1183 |         name: "action",
1184 |         description:
1185 |           "Action to perform (default: 'track'). Options: 'validate' (initialize metadata), 'track' (scan staleness), 'insights' (view trends)",
1186 |         required: false,
1187 |       },
1188 |     ],
1189 |   },
1190 | ];
1191 | 
1192 | // MCP resources should serve APPLICATION needs, not store tool results
1193 | // Resources are app-controlled and used for UI display, autocomplete, etc.
1194 | 
1195 | // Resource definitions following ADR-007 and MCP best practices
1196 | // Resources serve APPLICATIONS (UI needs) not tool result storage
1197 | const RESOURCES = [
1198 |   // Static Site Generators - for UI selection dropdowns
1199 |   {
1200 |     uri: "documcp://ssgs/available",
1201 |     name: "Available Static Site Generators",
1202 |     description: "List of supported SSGs with capabilities for UI selection",
1203 |     mimeType: "application/json",
1204 |   },
1205 |   // Templates - static templates for documentation setup
1206 |   {
1207 |     uri: "documcp://templates/jekyll-config",
1208 |     name: "Jekyll Configuration Template",
1209 |     description: "Template for Jekyll _config.yml",
1210 |     mimeType: "text/yaml",
1211 |   },
1212 |   {
1213 |     uri: "documcp://templates/hugo-config",
1214 |     name: "Hugo Configuration Template",
1215 |     description: "Template for Hugo config.yaml",
1216 |     mimeType: "text/yaml",
1217 |   },
1218 |   {
1219 |     uri: "documcp://templates/docusaurus-config",
1220 |     name: "Docusaurus Configuration Template",
1221 |     description: "Template for Docusaurus docusaurus.config.js",
1222 |     mimeType: "text/javascript",
1223 |   },
1224 |   {
1225 |     uri: "documcp://templates/mkdocs-config",
1226 |     name: "MkDocs Configuration Template",
1227 |     description: "Template for MkDocs mkdocs.yml",
1228 |     mimeType: "text/yaml",
1229 |   },
1230 |   {
1231 |     uri: "documcp://templates/eleventy-config",
1232 |     name: "Eleventy Configuration Template",
1233 |     description: "Template for Eleventy .eleventy.js",
1234 |     mimeType: "text/javascript",
1235 |   },
1236 |   {
1237 |     uri: "documcp://templates/diataxis-structure",
1238 |     name: "Diataxis Structure Template",
1239 |     description: "Diataxis documentation structure blueprint",
1240 |     mimeType: "application/json",
1241 |   },
1242 |   // Workflows - for UI to display available workflows
1243 |   {
1244 |     uri: "documcp://workflows/all",
1245 |     name: "All Documentation Workflows",
1246 |     description: "Complete list of available documentation workflows",
1247 |     mimeType: "application/json",
1248 |   },
1249 |   {
1250 |     uri: "documcp://workflows/quick-setup",
1251 |     name: "Quick Documentation Setup Workflow",
1252 |     description: "Fast-track workflow for basic documentation",
1253 |     mimeType: "application/json",
1254 |   },
1255 |   {
1256 |     uri: "documcp://workflows/full-setup",
1257 |     name: "Full Documentation Setup Workflow",
1258 |     description: "Comprehensive workflow for complete documentation",
1259 |     mimeType: "application/json",
1260 |   },
1261 |   {
1262 |     uri: "documcp://workflows/guidance",
1263 |     name: "Workflow Execution Guidance",
1264 |     description: "Guidelines for executing documentation workflows",
1265 |     mimeType: "application/json",
1266 |   },
1267 |   // Freshness tracking - for UI selection and configuration
1268 |   {
1269 |     uri: "documcp://freshness/presets",
1270 |     name: "Documentation Freshness Presets",
1271 |     description:
1272 |       "Available staleness threshold presets for UI selection (realtime, active, recent, weekly, monthly, quarterly)",
1273 |     mimeType: "application/json",
1274 |   },
1275 |   {
1276 |     uri: "documcp://freshness/metadata-schema",
1277 |     name: "Freshness Metadata Schema",
1278 |     description:
1279 |       "Schema for documentation frontmatter freshness metadata fields",
1280 |     mimeType: "application/json",
1281 |   },
1282 | ];
1283 | 
1284 | // List available tools
1285 | server.setRequestHandler(ListToolsRequestSchema, async () => ({
1286 |   tools: TOOLS.map((tool) => ({
1287 |     name: tool.name,
1288 |     description: tool.description,
1289 |     inputSchema: zodToJsonSchema(tool.inputSchema),
1290 |   })),
1291 | }));
1292 | 
1293 | // Helper function to detect documentation directories
1294 | async function detectDocsDirectories(
1295 |   projectRoot: string,
1296 | ): Promise<Array<{ path: string; name: string }>> {
1297 |   const commonDocsDirs = [
1298 |     "docs",
1299 |     "documentation",
1300 |     "doc",
1301 |     "wiki",
1302 |     "website/docs", // Docusaurus pattern
1303 |     ".vitepress", // VitePress
1304 |     "book", // mdBook
1305 |   ];
1306 | 
1307 |   const detected: Array<{ path: string; name: string }> = [];
1308 | 
1309 |   for (const dirName of commonDocsDirs) {
1310 |     const fullPath = path.join(projectRoot, dirName);
1311 |     try {
1312 |       const stats = await fs.stat(fullPath);
1313 |       if (stats.isDirectory()) {
1314 |         detected.push({
1315 |           path: fullPath,
1316 |           name: dirName,
1317 |         });
1318 |       }
1319 |     } catch {
1320 |       // Directory doesn't exist, skip
1321 |     }
1322 |   }
1323 | 
1324 |   return detected;
1325 | }
1326 | 
1327 | // List allowed roots (includes auto-detected docs directories)
1328 | server.setRequestHandler(ListRootsRequestSchema, async () => {
1329 |   const roots: Array<{
1330 |     uri: string;
1331 |     name: string;
1332 |     type?: string;
1333 |     description?: string;
1334 |     parent?: string;
1335 |   }> = [];
1336 | 
1337 |   // Add project roots
1338 |   for (const root of allowedRoots) {
1339 |     roots.push({
1340 |       uri: `file://${root}`,
1341 |       name: path.basename(root),
1342 |       type: "project",
1343 |       description: "Project root containing source code and documentation",
1344 |     });
1345 | 
1346 |     // Auto-detect and add docs directories within this root
1347 |     const docsDirectories = await detectDocsDirectories(root);
1348 |     for (const docsDir of docsDirectories) {
1349 |       roots.push({
1350 |         uri: `file://${docsDir.path}`,
1351 |         name: docsDir.name,
1352 |         type: "documentation",
1353 |         description: `Documentation directory within ${path.basename(root)}`,
1354 |         parent: `file://${root}`,
1355 |       });
1356 |     }
1357 |   }
1358 | 
1359 |   return { roots };
1360 | });
1361 | 
1362 | // List available prompts
1363 | server.setRequestHandler(ListPromptsRequestSchema, async () => ({
1364 |   prompts: PROMPTS,
1365 | }));
1366 | 
1367 | // Get specific prompt
1368 | server.setRequestHandler(GetPromptRequestSchema, async (request) => {
1369 |   const { name, arguments: args } = request.params;
1370 | 
1371 |   // Generate dynamic prompt messages using our Diataxis-aligned prompt system
1372 |   const projectPath = args?.project_path || process.cwd();
1373 |   const messages = await generateTechnicalWriterPrompts(
1374 |     name,
1375 |     projectPath,
1376 |     args || {},
1377 |   );
1378 | 
1379 |   return {
1380 |     description: `Technical writing assistance for ${name}`,
1381 |     messages,
1382 |   };
1383 | });
1384 | 
1385 | // List available resources
1386 | server.setRequestHandler(ListResourcesRequestSchema, async () => ({
1387 |   resources: RESOURCES,
1388 | }));
1389 | 
1390 | // Read specific resource
1391 | // Resources serve APPLICATION needs - static content for UI display
1392 | server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
1393 |   const { uri } = request.params;
1394 | 
1395 |   // Handle SSG list resource (for UI dropdowns/selection)
1396 |   if (uri === "documcp://ssgs/available") {
1397 |     return {
1398 |       contents: [
1399 |         {
1400 |           uri,
1401 |           mimeType: "application/json",
1402 |           text: JSON.stringify(
1403 |             {
1404 |               ssgs: [
1405 |                 {
1406 |                   id: "jekyll",
1407 |                   name: "Jekyll",
1408 |                   description: "Ruby-based SSG, great for GitHub Pages",
1409 |                   language: "ruby",
1410 |                   complexity: "low",
1411 |                   buildSpeed: "medium",
1412 |                   ecosystem: "mature",
1413 |                   bestFor: ["blogs", "documentation", "simple-sites"],
1414 |                 },
1415 |                 {
1416 |                   id: "hugo",
1417 |                   name: "Hugo",
1418 |                   description: "Go-based SSG, extremely fast builds",
1419 |                   language: "go",
1420 |                   complexity: "medium",
1421 |                   buildSpeed: "very-fast",
1422 |                   ecosystem: "mature",
1423 |                   bestFor: ["documentation", "blogs", "large-sites"],
1424 |                 },
1425 |                 {
1426 |                   id: "docusaurus",
1427 |                   name: "Docusaurus",
1428 |                   description:
1429 |                     "React-based, optimized for technical documentation",
1430 |                   language: "javascript",
1431 |                   complexity: "medium",
1432 |                   buildSpeed: "medium",
1433 |                   ecosystem: "growing",
1434 |                   bestFor: [
1435 |                     "technical-documentation",
1436 |                     "api-docs",
1437 |                     "versioned-docs",
1438 |                   ],
1439 |                 },
1440 |                 {
1441 |                   id: "mkdocs",
1442 |                   name: "MkDocs",
1443 |                   description: "Python-based, simple and fast documentation",
1444 |                   language: "python",
1445 |                   complexity: "low",
1446 |                   buildSpeed: "fast",
1447 |                   ecosystem: "mature",
1448 |                   bestFor: ["documentation", "technical-docs", "simple-setup"],
1449 |                 },
1450 |                 {
1451 |                   id: "eleventy",
1452 |                   name: "Eleventy",
1453 |                   description: "JavaScript-based, simple and flexible",
1454 |                   language: "javascript",
1455 |                   complexity: "low",
1456 |                   buildSpeed: "fast",
1457 |                   ecosystem: "growing",
1458 |                   bestFor: ["blogs", "documentation", "flexible-sites"],
1459 |                 },
1460 |               ],
1461 |             },
1462 |             null,
1463 |             2,
1464 |           ),
1465 |         },
1466 |       ],
1467 |     };
1468 |   }
1469 | 
1470 |   // Handle template resources (static content)
1471 |   if (uri.startsWith("documcp://templates/")) {
1472 |     const templateType = uri.split("/").pop();
1473 | 
1474 |     switch (templateType) {
1475 |       case "jekyll-config":
1476 |         return {
1477 |           contents: [
1478 |             {
1479 |               uri,
1480 |               mimeType: "text/yaml",
1481 |               text: `# Jekyll Configuration Template
1482 | title: "Documentation Site"
1483 | description: "Project documentation"
1484 | baseurl: ""
1485 | url: ""
1486 | 
1487 | markdown: kramdown
1488 | highlighter: rouge
1489 | theme: minima
1490 | 
1491 | plugins:
1492 |   - jekyll-feed
1493 |   - jekyll-sitemap
1494 | 
1495 | exclude:
1496 |   - Gemfile
1497 |   - Gemfile.lock
1498 |   - node_modules
1499 |   - vendor
1500 | `,
1501 |             },
1502 |           ],
1503 |         };
1504 | 
1505 |       case "hugo-config":
1506 |         return {
1507 |           contents: [
1508 |             {
1509 |               uri,
1510 |               mimeType: "text/yaml",
1511 |               text: `# Hugo Configuration Template
1512 | baseURL: "https://username.github.io/repository"
1513 | languageCode: "en-us"
1514 | title: "Documentation Site"
1515 | theme: "docsy"
1516 | 
1517 | params:
1518 |   github_repo: "https://github.com/username/repository"
1519 |   github_branch: "main"
1520 | 
1521 | markup:
1522 |   goldmark:
1523 |     renderer:
1524 |       unsafe: true
1525 |   highlight:
1526 |     style: github
1527 |     lineNos: true
1528 | `,
1529 |             },
1530 |           ],
1531 |         };
1532 | 
1533 |       case "docusaurus-config":
1534 |         return {
1535 |           contents: [
1536 |             {
1537 |               uri,
1538 |               mimeType: "text/javascript",
1539 |               text: `// Docusaurus Configuration Template
1540 | // @ts-check
1541 | 
1542 | /** @type {import('@docusaurus/types').Config} */
1543 | const config = {
1544 |   title: 'Documentation Site',
1545 |   tagline: 'Project documentation',
1546 |   url: 'https://username.github.io',
1547 |   baseUrl: '/repository/',
1548 |   onBrokenLinks: 'throw',
1549 |   onBrokenMarkdownLinks: 'warn',
1550 |   favicon: 'img/favicon.ico',
1551 | 
1552 |   organizationName: 'username',
1553 |   projectName: 'repository',
1554 | 
1555 |   i18n: {
1556 |     defaultLocale: 'en',
1557 |     locales: ['en'],
1558 |   },
1559 | 
1560 |   presets: [
1561 |     [
1562 |       'classic',
1563 |       /** @type {import('@docusaurus/preset-classic').Options} */
1564 |       ({
1565 |         docs: {
1566 |           sidebarPath: require.resolve('./sidebars.js'),
1567 |           editUrl: 'https://github.com/username/repository/tree/main/',
1568 |         },
1569 |         blog: false,
1570 |         theme: {
1571 |           customCss: require.resolve('./src/css/custom.css'),
1572 |         },
1573 |       }),
1574 |     ],
1575 |   ],
1576 | 
1577 |   themeConfig:
1578 |     /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
1579 |     ({
1580 |       navbar: {
1581 |         title: 'Documentation',
1582 |         items: [
1583 |           {
1584 |             type: 'doc',
1585 |             docId: 'intro',
1586 |             position: 'left',
1587 |             label: 'Tutorial',
1588 |           },
1589 |           {
1590 |             href: 'https://github.com/username/repository',
1591 |             label: 'GitHub',
1592 |             position: 'right',
1593 |           },
1594 |         ],
1595 |       },
1596 |       footer: {
1597 |         style: 'dark',
1598 |         copyright: \`Copyright © \${new Date().getFullYear()} Project Name\`,
1599 |       },
1600 |     }),
1601 | };
1602 | 
1603 | module.exports = config;
1604 | `,
1605 |             },
1606 |           ],
1607 |         };
1608 | 
1609 |       case "mkdocs-config":
1610 |         return {
1611 |           contents: [
1612 |             {
1613 |               uri,
1614 |               mimeType: "text/yaml",
1615 |               text: `# MkDocs Configuration Template
1616 | site_name: Documentation Site
1617 | site_url: https://username.github.io/repository
1618 | repo_url: https://github.com/username/repository
1619 | repo_name: username/repository
1620 | 
1621 | theme:
1622 |   name: material
1623 |   palette:
1624 |     - scheme: default
1625 |       primary: indigo
1626 |       accent: indigo
1627 |       toggle:
1628 |         icon: material/brightness-7
1629 |         name: Switch to dark mode
1630 |     - scheme: slate
1631 |       primary: indigo
1632 |       accent: indigo
1633 |       toggle:
1634 |         icon: material/brightness-4
1635 |         name: Switch to light mode
1636 |   features:
1637 |     - navigation.tabs
1638 |     - navigation.sections
1639 |     - toc.integrate
1640 |     - navigation.top
1641 |     - search.suggest
1642 |     - search.highlight
1643 |     - content.tabs.link
1644 | 
1645 | plugins:
1646 |   - search
1647 |   - awesome-pages
1648 | 
1649 | markdown_extensions:
1650 |   - pymdownx.highlight
1651 |   - pymdownx.superfences
1652 |   - pymdownx.tabbed
1653 |   - admonition
1654 |   - pymdownx.details
1655 | 
1656 | nav:
1657 |   - Home: index.md
1658 |   - Tutorials: tutorials/
1659 |   - How-To Guides: how-to/
1660 |   - Reference: reference/
1661 |   - Explanation: explanation/
1662 | `,
1663 |             },
1664 |           ],
1665 |         };
1666 | 
1667 |       case "eleventy-config":
1668 |         return {
1669 |           contents: [
1670 |             {
1671 |               uri,
1672 |               mimeType: "text/javascript",
1673 |               text: `// Eleventy Configuration Template
1674 | module.exports = function(eleventyConfig) {
1675 |   // Copy static assets
1676 |   eleventyConfig.addPassthroughCopy("src/css");
1677 |   eleventyConfig.addPassthroughCopy("src/js");
1678 |   eleventyConfig.addPassthroughCopy("src/images");
1679 | 
1680 |   // Add plugins
1681 |   // eleventyConfig.addPlugin(require("@11ty/eleventy-plugin-syntaxhighlight"));
1682 | 
1683 |   // Add filters
1684 |   eleventyConfig.addFilter("readableDate", dateObj => {
1685 |     return new Date(dateObj).toLocaleDateString();
1686 |   });
1687 | 
1688 |   // Add shortcodes
1689 |   eleventyConfig.addShortcode("year", () => \`\${new Date().getFullYear()}\`);
1690 | 
1691 |   // Markdown configuration
1692 |   let markdownIt = require("markdown-it");
1693 |   let markdownItAnchor = require("markdown-it-anchor");
1694 |   let options = {
1695 |     html: true,
1696 |     breaks: true,
1697 |     linkify: true
1698 |   };
1699 | 
1700 |   eleventyConfig.setLibrary("md", markdownIt(options)
1701 |     .use(markdownItAnchor)
1702 |   );
1703 | 
1704 |   return {
1705 |     dir: {
1706 |       input: "src",
1707 |       output: "_site",
1708 |       includes: "_includes",
1709 |       layouts: "_layouts",
1710 |       data: "_data"
1711 |     },
1712 |     templateFormats: ["md", "njk", "html"],
1713 |     markdownTemplateEngine: "njk",
1714 |     htmlTemplateEngine: "njk",
1715 |     dataTemplateEngine: "njk"
1716 |   };
1717 | };
1718 | `,
1719 |             },
1720 |           ],
1721 |         };
1722 | 
1723 |       case "diataxis-structure":
1724 |         return {
1725 |           contents: [
1726 |             {
1727 |               uri,
1728 |               mimeType: "application/json",
1729 |               text: JSON.stringify(
1730 |                 {
1731 |                   structure: {
1732 |                     tutorials: {
1733 |                       description: "Learning-oriented guides",
1734 |                       files: ["getting-started.md", "your-first-project.md"],
1735 |                     },
1736 |                     "how-to-guides": {
1737 |                       description: "Problem-oriented step-by-step guides",
1738 |                       files: ["common-tasks.md", "troubleshooting.md"],
1739 |                     },
1740 |                     reference: {
1741 |                       description: "Information-oriented technical reference",
1742 |                       files: ["api-reference.md", "configuration.md"],
1743 |                     },
1744 |                     explanation: {
1745 |                       description: "Understanding-oriented background material",
1746 |                       files: ["architecture.md", "design-decisions.md"],
1747 |                     },
1748 |                   },
1749 |                 },
1750 |                 null,
1751 |                 2,
1752 |               ),
1753 |             },
1754 |           ],
1755 |         };
1756 | 
1757 |       default:
1758 |         throw new Error(`Unknown template: ${templateType}`);
1759 |     }
1760 |   }
1761 | 
1762 |   // Handle workflow resources
1763 |   if (uri.startsWith("documcp://workflows/")) {
1764 |     const workflowType = uri.split("/").pop();
1765 | 
1766 |     switch (workflowType) {
1767 |       case "all":
1768 |         return {
1769 |           contents: [
1770 |             {
1771 |               uri,
1772 |               mimeType: "application/json",
1773 |               text: JSON.stringify(
1774 |                 {
1775 |                   workflows: DOCUMENTATION_WORKFLOWS,
1776 |                   executionGuidance: WORKFLOW_EXECUTION_GUIDANCE,
1777 |                   metadata: WORKFLOW_METADATA,
1778 |                 },
1779 |                 null,
1780 |                 2,
1781 |               ),
1782 |             },
1783 |           ],
1784 |         };
1785 | 
1786 |       case "quick-setup":
1787 |         return {
1788 |           contents: [
1789 |             {
1790 |               uri,
1791 |               mimeType: "application/json",
1792 |               text: JSON.stringify(
1793 |                 DOCUMENTATION_WORKFLOWS["quick-documentation-setup"],
1794 |                 null,
1795 |                 2,
1796 |               ),
1797 |             },
1798 |           ],
1799 |         };
1800 | 
1801 |       case "full-setup":
1802 |         return {
1803 |           contents: [
1804 |             {
1805 |               uri,
1806 |               mimeType: "application/json",
1807 |               text: JSON.stringify(
1808 |                 DOCUMENTATION_WORKFLOWS["full-documentation-setup"],
1809 |                 null,
1810 |                 2,
1811 |               ),
1812 |             },
1813 |           ],
1814 |         };
1815 | 
1816 |       case "guidance":
1817 |         return {
1818 |           contents: [
1819 |             {
1820 |               uri,
1821 |               mimeType: "application/json",
1822 |               text: JSON.stringify(
1823 |                 {
1824 |                   executionGuidance: WORKFLOW_EXECUTION_GUIDANCE,
1825 |                   recommendationEngine:
1826 |                     "Use recommendWorkflow() function with project status and requirements",
1827 |                 },
1828 |                 null,
1829 |                 2,
1830 |               ),
1831 |             },
1832 |           ],
1833 |         };
1834 | 
1835 |       default: {
1836 |         // Try to find specific workflow
1837 |         const workflow = DOCUMENTATION_WORKFLOWS[workflowType || ""];
1838 |         if (workflow) {
1839 |           return {
1840 |             contents: [
1841 |               {
1842 |                 uri,
1843 |                 mimeType: "application/json",
1844 |                 text: JSON.stringify(workflow, null, 2),
1845 |               },
1846 |             ],
1847 |           };
1848 |         }
1849 |         throw new Error(`Unknown workflow: ${workflowType}`);
1850 |       }
1851 |     }
1852 |   }
1853 | 
1854 |   // Handle freshness tracking resources
1855 |   if (uri.startsWith("documcp://freshness/")) {
1856 |     const freshnessType = uri.split("/").pop();
1857 | 
1858 |     switch (freshnessType) {
1859 |       case "presets":
1860 |         return {
1861 |           contents: [
1862 |             {
1863 |               uri,
1864 |               mimeType: "application/json",
1865 |               text: JSON.stringify(
1866 |                 {
1867 |                   presets: [
1868 |                     {
1869 |                       id: "realtime",
1870 |                       name: "Realtime",
1871 |                       description:
1872 |                         "For frequently updated documentation (minutes)",
1873 |                       thresholds: {
1874 |                         warning: { value: 5, unit: "minutes" },
1875 |                         stale: { value: 15, unit: "minutes" },
1876 |                         critical: { value: 30, unit: "minutes" },
1877 |                       },
1878 |                       bestFor: ["api-docs", "status-pages", "live-updates"],
1879 |                     },
1880 |                     {
1881 |                       id: "active",
1882 |                       name: "Active",
1883 |                       description:
1884 |                         "For actively maintained documentation (hours)",
1885 |                       thresholds: {
1886 |                         warning: { value: 2, unit: "hours" },
1887 |                         stale: { value: 6, unit: "hours" },
1888 |                         critical: { value: 12, unit: "hours" },
1889 |                       },
1890 |                       bestFor: [
1891 |                         "development-docs",
1892 |                         "feature-guides",
1893 |                         "release-notes",
1894 |                       ],
1895 |                     },
1896 |                     {
1897 |                       id: "recent",
1898 |                       name: "Recent",
1899 |                       description: "For regularly updated documentation (days)",
1900 |                       thresholds: {
1901 |                         warning: { value: 1, unit: "days" },
1902 |                         stale: { value: 3, unit: "days" },
1903 |                         critical: { value: 7, unit: "days" },
1904 |                       },
1905 |                       bestFor: [
1906 |                         "tutorials",
1907 |                         "getting-started",
1908 |                         "project-updates",
1909 |                       ],
1910 |                     },
1911 |                     {
1912 |                       id: "weekly",
1913 |                       name: "Weekly",
1914 |                       description: "For weekly maintenance cycle (7 days)",
1915 |                       thresholds: {
1916 |                         warning: { value: 7, unit: "days" },
1917 |                         stale: { value: 14, unit: "days" },
1918 |                         critical: { value: 30, unit: "days" },
1919 |                       },
1920 |                       bestFor: ["how-to-guides", "examples", "best-practices"],
1921 |                     },
1922 |                     {
1923 |                       id: "monthly",
1924 |                       name: "Monthly",
1925 |                       description:
1926 |                         "For monthly maintenance cycle (30 days) - DEFAULT",
1927 |                       thresholds: {
1928 |                         warning: { value: 30, unit: "days" },
1929 |                         stale: { value: 60, unit: "days" },
1930 |                         critical: { value: 90, unit: "days" },
1931 |                       },
1932 |                       bestFor: [
1933 |                         "reference-docs",
1934 |                         "architecture",
1935 |                         "stable-features",
1936 |                       ],
1937 |                       default: true,
1938 |                     },
1939 |                     {
1940 |                       id: "quarterly",
1941 |                       name: "Quarterly",
1942 |                       description: "For quarterly maintenance cycle (90 days)",
1943 |                       thresholds: {
1944 |                         warning: { value: 90, unit: "days" },
1945 |                         stale: { value: 180, unit: "days" },
1946 |                         critical: { value: 365, unit: "days" },
1947 |                       },
1948 |                       bestFor: [
1949 |                         "explanations",
1950 |                         "background",
1951 |                         "rarely-changing-docs",
1952 |                       ],
1953 |                     },
1954 |                   ],
1955 |                 },
1956 |                 null,
1957 |                 2,
1958 |               ),
1959 |             },
1960 |           ],
1961 |         };
1962 | 
1963 |       case "metadata-schema":
1964 |         return {
1965 |           contents: [
1966 |             {
1967 |               uri,
1968 |               mimeType: "application/json",
1969 |               text: JSON.stringify(
1970 |                 {
1971 |                   schema: {
1972 |                     documcp: {
1973 |                       description: "DocuMCP metadata block in YAML frontmatter",
1974 |                       type: "object",
1975 |                       properties: {
1976 |                         last_updated: {
1977 |                           type: "string",
1978 |                           format: "date-time",
1979 |                           description:
1980 |                             "ISO 8601 timestamp of last content update",
1981 |                           example: "2025-01-19T10:30:00Z",
1982 |                         },
1983 |                         last_validated: {
1984 |                           type: "string",
1985 |                           format: "date-time",
1986 |                           description:
1987 |                             "ISO 8601 timestamp of last validation check",
1988 |                           example: "2025-01-19T10:30:00Z",
1989 |                         },
1990 |                         update_frequency: {
1991 |                           type: "string",
1992 |                           enum: [
1993 |                             "realtime",
1994 |                             "active",
1995 |                             "recent",
1996 |                             "weekly",
1997 |                             "monthly",
1998 |                             "quarterly",
1999 |                           ],
2000 |                           description: "Expected update frequency preset",
2001 |                           default: "monthly",
2002 |                         },
2003 |                         validated_against_commit: {
2004 |                           type: "string",
2005 |                           description:
2006 |                             "Git commit hash the documentation was validated against",
2007 |                           example: "a1b2c3d",
2008 |                         },
2009 |                         auto_updated: {
2010 |                           type: "boolean",
2011 |                           description:
2012 |                             "Whether timestamps are automatically updated",
2013 |                           default: false,
2014 |                         },
2015 |                       },
2016 |                       required: ["last_updated"],
2017 |                     },
2018 |                   },
2019 |                   example: {
2020 |                     yaml: `---
2021 | title: "API Reference"
2022 | description: "Complete API documentation"
2023 | documcp:
2024 |   last_updated: "2025-01-19T10:30:00Z"
2025 |   last_validated: "2025-01-19T10:30:00Z"
2026 |   update_frequency: "monthly"
2027 |   validated_against_commit: "a1b2c3d"
2028 |   auto_updated: false
2029 | ---`,
2030 |                   },
2031 |                 },
2032 |                 null,
2033 |                 2,
2034 |               ),
2035 |             },
2036 |           ],
2037 |         };
2038 | 
2039 |       default:
2040 |         throw new Error(`Unknown freshness resource: ${freshnessType}`);
2041 |     }
2042 |   }
2043 | 
2044 |   throw new Error(`Resource not found: ${uri}`);
2045 | });
2046 | 
2047 | // Helper to wrap tool results in standard MCP format
2048 | function wrapToolResult<T>(result: T, _toolName: string) {
2049 |   // If result is already in MCP format (has 'content' array), return as-is
2050 |   if (
2051 |     result &&
2052 |     typeof result === "object" &&
2053 |     "content" in result &&
2054 |     Array.isArray((result as any).content)
2055 |   ) {
2056 |     return result;
2057 |   }
2058 | 
2059 |   // Otherwise, wrap in formatMCPResponse
2060 |   return formatMCPResponse({
2061 |     success: true,
2062 |     data: result,
2063 |     metadata: {
2064 |       toolVersion: packageJson.version,
2065 |       executionTime: Date.now(),
2066 |       timestamp: new Date().toISOString(),
2067 |     },
2068 |   });
2069 | }
2070 | 
2071 | // Handle tool execution
2072 | server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
2073 |   const { name, arguments: args } = request.params;
2074 | 
2075 |   try {
2076 |     switch (name) {
2077 |       case "analyze_repository": {
2078 |         // Check if path is allowed
2079 |         const repoPath = (args as any)?.path;
2080 |         if (repoPath && !isPathAllowed(repoPath, allowedRoots)) {
2081 |           return formatMCPResponse({
2082 |             success: false,
2083 |             error: {
2084 |               code: "PERMISSION_DENIED",
2085 |               message: getPermissionDeniedMessage(repoPath, allowedRoots),
2086 |               resolution:
2087 |                 "Request access to this directory by starting the server with --root argument, or use a path within allowed roots.",
2088 |             },
2089 |             metadata: {
2090 |               toolVersion: packageJson.version,
2091 |               executionTime: 0,
2092 |               timestamp: new Date().toISOString(),
2093 |             },
2094 |           });
2095 |         }
2096 | 
2097 |         const result = await analyzeRepository(args, extra);
2098 | 
2099 |         // Remember in persistent memory
2100 |         if (args?.path && typeof args.path === "string") {
2101 |           const memoryId = await rememberAnalysis(args.path, result);
2102 |           (result as any).memoryId = memoryId;
2103 | 
2104 |           // Get insights from similar projects
2105 |           const similarProjects = await getSimilarProjects(result, 3);
2106 |           if (similarProjects.length > 0) {
2107 |             (result as any).insights = {
2108 |               similarProjects,
2109 |               message: `Found ${similarProjects.length} similar projects in memory`,
2110 |             };
2111 |           }
2112 |         }
2113 | 
2114 |         return wrapToolResult(result, "analyze_repository");
2115 |       }
2116 | 
2117 |       case "recommend_ssg": {
2118 |         const result = await recommendSSG(args, extra);
2119 | 
2120 |         // Remember recommendation
2121 |         if (args?.analysisId && typeof args.analysisId === "string") {
2122 |           const memoryId = await rememberRecommendation(
2123 |             args.analysisId,
2124 |             result,
2125 |           );
2126 |           (result as any).memoryId = memoryId;
2127 | 
2128 |           // Get project history if available
2129 |           const projectInsights = await getProjectInsights(args.analysisId);
2130 |           if (projectInsights.length > 0) {
2131 |             (result as any).projectHistory = projectInsights;
2132 |           }
2133 |         }
2134 |         return wrapToolResult(result, "recommend_ssg");
2135 |       }
2136 | 
2137 |       case "generate_config": {
2138 |         const result = await generateConfig(args);
2139 |         return wrapToolResult(result, "generate_config");
2140 |       }
2141 | 
2142 |       case "setup_structure": {
2143 |         // Check if basePath is allowed
2144 |         const basePath = (args as any)?.basePath;
2145 |         if (basePath && !isPathAllowed(basePath, allowedRoots)) {
2146 |           return formatMCPResponse({
2147 |             success: false,
2148 |             error: {
2149 |               code: "PERMISSION_DENIED",
2150 |               message: getPermissionDeniedMessage(basePath, allowedRoots),
2151 |               resolution:
2152 |                 "Request access to this directory by starting the server with --root argument.",
2153 |             },
2154 |             metadata: {
2155 |               toolVersion: packageJson.version,
2156 |               executionTime: 0,
2157 |               timestamp: new Date().toISOString(),
2158 |             },
2159 |           });
2160 |         }
2161 | 
2162 |         const result = await setupStructure(args);
2163 |         return wrapToolResult(result, "setup_structure");
2164 |       }
2165 | 
2166 |       case "setup_playwright_tests": {
2167 |         const result = await setupPlaywrightTests(args);
2168 |         return wrapToolResult(result, "setup_playwright_tests");
2169 |       }
2170 | 
2171 |       case "deploy_pages": {
2172 |         const result = await deployPages(args, extra);
2173 |         return wrapToolResult(result, "deploy_pages");
2174 |       }
2175 | 
2176 |       case "verify_deployment": {
2177 |         const result = await verifyDeployment(args);
2178 |         return wrapToolResult(result, "verify_deployment");
2179 |       }
2180 | 
2181 |       case "populate_diataxis_content": {
2182 |         // Check if docsPath is allowed
2183 |         const docsPath = (args as any)?.docsPath;
2184 |         if (docsPath && !isPathAllowed(docsPath, allowedRoots)) {
2185 |           return formatMCPResponse({
2186 |             success: false,
2187 |             error: {
2188 |               code: "PERMISSION_DENIED",
2189 |               message: getPermissionDeniedMessage(docsPath, allowedRoots),
2190 |               resolution:
2191 |                 "Request access to this directory by starting the server with --root argument.",
2192 |             },
2193 |             metadata: {
2194 |               toolVersion: packageJson.version,
2195 |               executionTime: 0,
2196 |               timestamp: new Date().toISOString(),
2197 |             },
2198 |           });
2199 |         }
2200 | 
2201 |         const result = await handlePopulateDiataxisContent(args, extra);
2202 |         return {
2203 |           content: [
2204 |             {
2205 |               type: "text",
2206 |               text: `Content population completed successfully. Generated ${
2207 |                 result.filesCreated
2208 |               } files with ${Math.round(
2209 |                 result.populationMetrics.coverage,
2210 |               )}% coverage.`,
2211 |             },
2212 |             {
2213 |               type: "text",
2214 |               text: `Population metrics: Coverage: ${result.populationMetrics.coverage}%, Completeness: ${result.populationMetrics.completeness}%, Project Specificity: ${result.populationMetrics.projectSpecificity}%`,
2215 |             },
2216 |             {
2217 |               type: "text",
2218 |               text: `Next steps:\n${result.nextSteps
2219 |                 .map((step) => `- ${step}`)
2220 |                 .join("\n")}`,
2221 |             },
2222 |           ],
2223 |         };
2224 |       }
2225 | 
2226 |       case "update_existing_documentation": {
2227 |         const result = await handleUpdateExistingDocumentation(args);
2228 |         return {
2229 |           content: [
2230 |             {
2231 |               type: "text",
2232 |               text: `Documentation analysis completed. Found ${result.updateMetrics.gapsDetected} gaps and generated ${result.updateMetrics.recommendationsGenerated} recommendations.`,
2233 |             },
2234 |             {
2235 |               type: "text",
2236 |               text: `Update metrics: Confidence Score: ${result.updateMetrics.confidenceScore}, Estimated Effort: ${result.updateMetrics.estimatedEffort}`,
2237 |             },
2238 |             {
2239 |               type: "text",
2240 |               text: `Memory insights: ${result.memoryInsights.similarProjects.length} similar projects analyzed, ${result.memoryInsights.successfulUpdatePatterns.length} successful update patterns found`,
2241 |             },
2242 |             {
2243 |               type: "text",
2244 |               text: `Top recommendations:\n${result.recommendations
2245 |                 .slice(0, 5)
2246 |                 .map(
2247 |                   (rec, i) =>
2248 |                     `${i + 1}. ${rec.reasoning} (confidence: ${Math.round(
2249 |                       rec.confidence * 100,
2250 |                     )}%)`,
2251 |                 )
2252 |                 .join("\n")}`,
2253 |             },
2254 |             {
2255 |               type: "text",
2256 |               text: `Next steps:\n${result.nextSteps
2257 |                 .map((step) => `- ${step}`)
2258 |                 .join("\n")}`,
2259 |             },
2260 |           ],
2261 |         };
2262 |       }
2263 | 
2264 |       case "validate_diataxis_content": {
2265 |         // Check if contentPath is allowed
2266 |         const contentPath = (args as any)?.contentPath;
2267 |         if (contentPath && !isPathAllowed(contentPath, allowedRoots)) {
2268 |           return formatMCPResponse({
2269 |             success: false,
2270 |             error: {
2271 |               code: "PERMISSION_DENIED",
2272 |               message: getPermissionDeniedMessage(contentPath, allowedRoots),
2273 |               resolution:
2274 |                 "Request access to this directory by starting the server with --root argument.",
2275 |             },
2276 |             metadata: {
2277 |               toolVersion: packageJson.version,
2278 |               executionTime: 0,
2279 |               timestamp: new Date().toISOString(),
2280 |             },
2281 |           });
2282 |         }
2283 | 
2284 |         const result = await handleValidateDiataxisContent(args, extra);
2285 | 
2286 |         // Return structured validation results as JSON
2287 |         const validationSummary = {
2288 |           status: result.success ? "PASSED" : "ISSUES FOUND",
2289 |           confidence: `${result.confidence.overall}%`,
2290 |           issuesFound: result.issues.length,
2291 |           breakdown: {
2292 |             errors: result.issues.filter((i) => i.type === "error").length,
2293 |             warnings: result.issues.filter((i) => i.type === "warning").length,
2294 |             info: result.issues.filter((i) => i.type === "info").length,
2295 |           },
2296 |           topIssues: result.issues.slice(0, 5).map((issue) => ({
2297 |             type: issue.type.toUpperCase(),
2298 |             category: issue.category,
2299 |             file: issue.location.file,
2300 |             description: issue.description,
2301 |           })),
2302 |           recommendations: result.recommendations,
2303 |           nextSteps: result.nextSteps,
2304 |           confidenceBreakdown: result.confidence.breakdown,
2305 |         };
2306 | 
2307 |         return {
2308 |           content: [
2309 |             {
2310 |               type: "text",
2311 |               text: `Content validation ${
2312 |                 result.success ? "passed" : "found issues"
2313 |               }. Overall confidence: ${result.confidence.overall}%.`,
2314 |             },
2315 |             {
2316 |               type: "text",
2317 |               text: `Issues found: ${result.issues.length} (${
2318 |                 result.issues.filter((i) => i.type === "error").length
2319 |               } errors, ${
2320 |                 result.issues.filter((i) => i.type === "warning").length
2321 |               } warnings)`,
2322 |             },
2323 |             {
2324 |               type: "text",
2325 |               text: JSON.stringify(validationSummary, null, 2),
2326 |             },
2327 |           ],
2328 |         };
2329 |       }
2330 | 
2331 |       case "validate_content": {
2332 |         const result = await validateGeneralContent(args);
2333 | 
2334 |         // Return structured validation results as JSON
2335 |         const contentSummary = {
2336 |           status: result.success ? "PASSED" : "ISSUES FOUND",
2337 |           summary: result.summary,
2338 |           linksChecked: result.linksChecked || 0,
2339 |           codeBlocksValidated: result.codeBlocksValidated || 0,
2340 |           brokenLinks: result.brokenLinks || [],
2341 |           codeErrors: (result.codeErrors || []).slice(0, 10), // Limit to first 10 errors
2342 |           recommendations: result.recommendations || [],
2343 |         };
2344 | 
2345 |         return {
2346 |           content: [
2347 |             {
2348 |               type: "text",
2349 |               text: `Content validation completed. Status: ${
2350 |                 result.success ? "PASSED" : "ISSUES FOUND"
2351 |               }`,
2352 |             },
2353 |             {
2354 |               type: "text",
2355 |               text: `Results: ${result.linksChecked || 0} links checked, ${
2356 |                 result.codeBlocksValidated || 0
2357 |               } code blocks validated`,
2358 |             },
2359 |             {
2360 |               type: "text",
2361 |               text: JSON.stringify(contentSummary, null, 2),
2362 |             },
2363 |           ],
2364 |         };
2365 |       }
2366 | 
2367 |       case "detect_documentation_gaps": {
2368 |         const result = await detectDocumentationGaps(args);
2369 |         return wrapToolResult(result, "detect_documentation_gaps");
2370 |       }
2371 | 
2372 |       case "test_local_deployment": {
2373 |         const result = await testLocalDeployment(args);
2374 |         return wrapToolResult(result, "test_local_deployment");
2375 |       }
2376 | 
2377 |       case "evaluate_readme_health": {
2378 |         const result = await evaluateReadmeHealth(args as any);
2379 |         return wrapToolResult(result, "evaluate_readme_health");
2380 |       }
2381 | 
2382 |       case "readme_best_practices": {
2383 |         const result = await readmeBestPractices(args as any);
2384 |         return formatMCPResponse(result);
2385 |       }
2386 | 
2387 |       case "check_documentation_links": {
2388 |         // Check if documentation_path is allowed
2389 |         const docLinksPath = (args as any)?.documentation_path;
2390 |         if (docLinksPath && !isPathAllowed(docLinksPath, allowedRoots)) {
2391 |           return formatMCPResponse({
2392 |             success: false,
2393 |             error: {
2394 |               code: "PERMISSION_DENIED",
2395 |               message: getPermissionDeniedMessage(docLinksPath, allowedRoots),
2396 |               resolution:
2397 |                 "Request access to this directory by starting the server with --root argument.",
2398 |             },
2399 |             metadata: {
2400 |               toolVersion: packageJson.version,
2401 |               executionTime: 0,
2402 |               timestamp: new Date().toISOString(),
2403 |             },
2404 |           });
2405 |         }
2406 | 
2407 |         const result = await checkDocumentationLinks(args as any);
2408 |         return formatMCPResponse(result);
2409 |       }
2410 | 
2411 |       case "generate_readme_template": {
2412 |         const result = await generateReadmeTemplate(args as any);
2413 |         return formatMCPResponse({
2414 |           success: true,
2415 |           data: result,
2416 |           metadata: {
2417 |             toolVersion: packageJson.version,
2418 |             executionTime: Date.now(),
2419 |             timestamp: new Date().toISOString(),
2420 |           },
2421 |         });
2422 |       }
2423 | 
2424 |       case "validate_readme_checklist": {
2425 |         const result = await validateReadmeChecklist(args as any);
2426 |         return formatMCPResponse({
2427 |           success: true,
2428 |           data: result,
2429 |           metadata: {
2430 |             toolVersion: packageJson.version,
2431 |             executionTime: Date.now(),
2432 |             timestamp: new Date().toISOString(),
2433 |           },
2434 |         });
2435 |       }
2436 | 
2437 |       case "analyze_readme": {
2438 |         const result = await analyzeReadme(args as any);
2439 |         return formatMCPResponse(result);
2440 |       }
2441 | 
2442 |       case "manage_preferences": {
2443 |         const result = await managePreferences(args);
2444 |         return wrapToolResult(result, "manage_preferences");
2445 |       }
2446 | 
2447 |       case "analyze_deployments": {
2448 |         const result = await analyzeDeployments(args);
2449 |         return wrapToolResult(result, "analyze_deployments");
2450 |       }
2451 | 
2452 |       // Phase 3: Code-to-Documentation Synchronization
2453 |       case "sync_code_to_docs": {
2454 |         const projectPath = (args as any)?.projectPath;
2455 |         const docsPath = (args as any)?.docsPath;
2456 | 
2457 |         // Check if paths are allowed
2458 |         if (projectPath && !isPathAllowed(projectPath, allowedRoots)) {
2459 |           return formatMCPResponse({
2460 |             success: false,
2461 |             error: {
2462 |               code: "PERMISSION_DENIED",
2463 |               message: getPermissionDeniedMessage(projectPath, allowedRoots),
2464 |               resolution:
2465 |                 "Request access to this directory by starting the server with --root argument",
2466 |             },
2467 |             metadata: {
2468 |               toolVersion: packageJson.version,
2469 |               executionTime: 0,
2470 |               timestamp: new Date().toISOString(),
2471 |             },
2472 |           });
2473 |         }
2474 | 
2475 |         if (docsPath && !isPathAllowed(docsPath, allowedRoots)) {
2476 |           return formatMCPResponse({
2477 |             success: false,
2478 |             error: {
2479 |               code: "PERMISSION_DENIED",
2480 |               message: getPermissionDeniedMessage(docsPath, allowedRoots),
2481 |               resolution:
2482 |                 "Request access to this directory by starting the server with --root argument",
2483 |             },
2484 |             metadata: {
2485 |               toolVersion: packageJson.version,
2486 |               executionTime: 0,
2487 |               timestamp: new Date().toISOString(),
2488 |             },
2489 |           });
2490 |         }
2491 | 
2492 |         const result = await handleSyncCodeToDocs(args, extra);
2493 |         return wrapToolResult(result, "sync_code_to_docs");
2494 |       }
2495 | 
2496 |       case "generate_contextual_content": {
2497 |         const filePath = (args as any)?.filePath;
2498 | 
2499 |         // Check if file path is allowed
2500 |         if (filePath && !isPathAllowed(filePath, allowedRoots)) {
2501 |           return formatMCPResponse({
2502 |             success: false,
2503 |             error: {
2504 |               code: "PERMISSION_DENIED",
2505 |               message: getPermissionDeniedMessage(filePath, allowedRoots),
2506 |               resolution:
2507 |                 "Request access to this file by starting the server with --root argument",
2508 |             },
2509 |             metadata: {
2510 |               toolVersion: packageJson.version,
2511 |               executionTime: 0,
2512 |               timestamp: new Date().toISOString(),
2513 |             },
2514 |           });
2515 |         }
2516 | 
2517 |         const result = await handleGenerateContextualContent(args, extra);
2518 |         return wrapToolResult(result, "generate_contextual_content");
2519 |       }
2520 | 
2521 |       // Documentation Freshness Tracking
2522 |       case "track_documentation_freshness": {
2523 |         const docsPath = (args as any)?.docsPath;
2524 | 
2525 |         // Check if docs path is allowed
2526 |         if (docsPath && !isPathAllowed(docsPath, allowedRoots)) {
2527 |           return formatMCPResponse({
2528 |             success: false,
2529 |             error: {
2530 |               code: "PERMISSION_DENIED",
2531 |               message: getPermissionDeniedMessage(docsPath, allowedRoots),
2532 |               resolution:
2533 |                 "Request access to this directory by starting the server with --root argument",
2534 |             },
2535 |             metadata: {
2536 |               toolVersion: packageJson.version,
2537 |               executionTime: 0,
2538 |               timestamp: new Date().toISOString(),
2539 |             },
2540 |           });
2541 |         }
2542 | 
2543 |         const result = await trackDocumentationFreshness(args as any);
2544 |         return wrapToolResult(result, "track_documentation_freshness");
2545 |       }
2546 | 
2547 |       case "validate_documentation_freshness": {
2548 |         const docsPath = (args as any)?.docsPath;
2549 |         const projectPath = (args as any)?.projectPath;
2550 | 
2551 |         // Check if paths are allowed
2552 |         if (docsPath && !isPathAllowed(docsPath, allowedRoots)) {
2553 |           return formatMCPResponse({
2554 |             success: false,
2555 |             error: {
2556 |               code: "PERMISSION_DENIED",
2557 |               message: getPermissionDeniedMessage(docsPath, allowedRoots),
2558 |               resolution:
2559 |                 "Request access to this directory by starting the server with --root argument",
2560 |             },
2561 |             metadata: {
2562 |               toolVersion: packageJson.version,
2563 |               executionTime: 0,
2564 |               timestamp: new Date().toISOString(),
2565 |             },
2566 |           });
2567 |         }
2568 | 
2569 |         if (projectPath && !isPathAllowed(projectPath, allowedRoots)) {
2570 |           return formatMCPResponse({
2571 |             success: false,
2572 |             error: {
2573 |               code: "PERMISSION_DENIED",
2574 |               message: getPermissionDeniedMessage(projectPath, allowedRoots),
2575 |               resolution:
2576 |                 "Request access to this directory by starting the server with --root argument",
2577 |             },
2578 |             metadata: {
2579 |               toolVersion: packageJson.version,
2580 |               executionTime: 0,
2581 |               timestamp: new Date().toISOString(),
2582 |             },
2583 |           });
2584 |         }
2585 | 
2586 |         const result = await validateDocumentationFreshness(args as any);
2587 |         return wrapToolResult(result, "validate_documentation_freshness");
2588 |       }
2589 | 
2590 |       case "manage_sitemap": {
2591 |         const docsPath = (args as any)?.docsPath;
2592 | 
2593 |         // Check if docs path is allowed
2594 |         if (docsPath && !isPathAllowed(docsPath, allowedRoots)) {
2595 |           return formatMCPResponse({
2596 |             success: false,
2597 |             error: {
2598 |               code: "PERMISSION_DENIED",
2599 |               message: getPermissionDeniedMessage(docsPath, allowedRoots),
2600 |               resolution:
2601 |                 "Request access to this directory by starting the server with --root argument",
2602 |             },
2603 |             metadata: {
2604 |               toolVersion: packageJson.version,
2605 |               executionTime: 0,
2606 |               timestamp: new Date().toISOString(),
2607 |             },
2608 |           });
2609 |         }
2610 | 
2611 |         const result = await manageSitemap(args as any);
2612 |         return wrapToolResult(result, "manage_sitemap");
2613 |       }
2614 | 
2615 |       case "generate_llm_context": {
2616 |         const projectPath = (args as any)?.projectPath;
2617 | 
2618 |         // Check if project path is allowed
2619 |         if (projectPath && !isPathAllowed(projectPath, allowedRoots)) {
2620 |           return formatMCPResponse({
2621 |             success: false,
2622 |             error: {
2623 |               code: "PERMISSION_DENIED",
2624 |               message: getPermissionDeniedMessage(projectPath, allowedRoots),
2625 |               resolution:
2626 |                 "Request access to this directory by starting the server with --root argument",
2627 |             },
2628 |             metadata: {
2629 |               toolVersion: packageJson.version,
2630 |               executionTime: 0,
2631 |               timestamp: new Date().toISOString(),
2632 |             },
2633 |           });
2634 |         }
2635 | 
2636 |         const result = await generateLLMContext(args as any);
2637 |         return wrapToolResult(result, "generate_llm_context");
2638 |       }
2639 | 
2640 |       case "read_directory": {
2641 |         const { path: dirPath } = args as { path: string };
2642 | 
2643 |         // Check if path is allowed
2644 |         if (!isPathAllowed(dirPath, allowedRoots)) {
2645 |           return formatMCPResponse({
2646 |             success: false,
2647 |             error: {
2648 |               code: "PERMISSION_DENIED",
2649 |               message: getPermissionDeniedMessage(dirPath, allowedRoots),
2650 |               resolution:
2651 |                 "Request access to this directory by starting the server with --root argument, or use a path within allowed roots.",
2652 |             },
2653 |             metadata: {
2654 |               toolVersion: packageJson.version,
2655 |               executionTime: 0,
2656 |               timestamp: new Date().toISOString(),
2657 |             },
2658 |           });
2659 |         }
2660 | 
2661 |         try {
2662 |           const entries = await fs.readdir(dirPath, { withFileTypes: true });
2663 |           const files = [];
2664 |           const directories = [];
2665 | 
2666 |           for (const entry of entries) {
2667 |             if (entry.isDirectory()) {
2668 |               directories.push(entry.name);
2669 |             } else if (entry.isFile()) {
2670 |               files.push(entry.name);
2671 |             }
2672 |           }
2673 | 
2674 |           return formatMCPResponse({
2675 |             success: true,
2676 |             data: {
2677 |               path: dirPath,
2678 |               files,
2679 |               directories,
2680 |               totalFiles: files.length,
2681 |               totalDirectories: directories.length,
2682 |             },
2683 |             metadata: {
2684 |               toolVersion: packageJson.version,
2685 |               executionTime: 0,
2686 |               timestamp: new Date().toISOString(),
2687 |             },
2688 |           });
2689 |         } catch (error: any) {
2690 |           return formatMCPResponse({
2691 |             success: false,
2692 |             error: {
2693 |               code: "READ_DIRECTORY_FAILED",
2694 |               message: `Failed to read directory: ${error.message}`,
2695 |               resolution: "Ensure the directory exists and is accessible.",
2696 |             },
2697 |             metadata: {
2698 |               toolVersion: packageJson.version,
2699 |               executionTime: 0,
2700 |               timestamp: new Date().toISOString(),
2701 |             },
2702 |           });
2703 |         }
2704 |       }
2705 | 
2706 |       case "optimize_readme": {
2707 |         const result = await optimizeReadme(args as any);
2708 |         return formatMCPResponse(result);
2709 |       }
2710 | 
2711 |       // Memory system tools
2712 |       case "memory_recall": {
2713 |         await initializeMemory(); // Ensure memory is initialized
2714 |         const manager = (await import("./memory/index.js")).getMemoryManager();
2715 |         if (!manager) throw new Error("Memory system not initialized");
2716 | 
2717 |         let results;
2718 |         if (args?.type === "all") {
2719 |           results = await manager.search(args?.query || "", {
2720 |             sortBy: "timestamp",
2721 |           });
2722 |         } else {
2723 |           results = await manager.search(args?.type || "analysis", {
2724 |             sortBy: "timestamp",
2725 |           });
2726 |         }
2727 | 
2728 |         if (args?.limit && typeof args.limit === "number") {
2729 |           results = results.slice(0, args.limit);
2730 |         }
2731 | 
2732 |         return {
2733 |           content: [
2734 |             {
2735 |               type: "text",
2736 |               text: `Found ${results.length} memories`,
2737 |             },
2738 |             {
2739 |               type: "text",
2740 |               text: JSON.stringify(results, null, 2),
2741 |             },
2742 |           ],
2743 |         };
2744 |       }
2745 | 
2746 |       case "memory_insights": {
2747 |         const insights = await getMemoryStatistics();
2748 |         if (args?.projectId && typeof args.projectId === "string") {
2749 |           const projectInsights = await getProjectInsights(args.projectId);
2750 |           (insights as any).projectSpecific = projectInsights;
2751 |         }
2752 | 
2753 |         return {
2754 |           content: [
2755 |             {
2756 |               type: "text",
2757 |               text: "Memory system insights and patterns",
2758 |             },
2759 |             {
2760 |               type: "text",
2761 |               text: JSON.stringify(insights, null, 2),
2762 |             },
2763 |           ],
2764 |         };
2765 |       }
2766 | 
2767 |       case "memory_similar": {
2768 |         await initializeMemory();
2769 |         const manager = (await import("./memory/index.js")).getMemoryManager();
2770 |         if (!manager) throw new Error("Memory system not initialized");
2771 | 
2772 |         if (!args?.analysisId || typeof args.analysisId !== "string") {
2773 |           throw new Error("analysisId is required");
2774 |         }
2775 | 
2776 |         const analysis = await manager.recall(args.analysisId);
2777 |         if (!analysis) {
2778 |           throw new Error(`Analysis ${args.analysisId} not found in memory`);
2779 |         }
2780 | 
2781 |         const limitValue = typeof args?.limit === "number" ? args.limit : 5;
2782 |         const similar = await getSimilarProjects(analysis.data, limitValue);
2783 | 
2784 |         return {
2785 |           content: [
2786 |             {
2787 |               type: "text",
2788 |               text: `Found ${similar.length} similar projects`,
2789 |             },
2790 |             {
2791 |               type: "text",
2792 |               text: JSON.stringify(similar, null, 2),
2793 |             },
2794 |           ],
2795 |         };
2796 |       }
2797 | 
2798 |       case "memory_export": {
2799 |         const format =
2800 |           args?.format === "json" || args?.format === "csv"
2801 |             ? args.format
2802 |             : "json";
2803 |         const exported = await exportMemories(format);
2804 | 
2805 |         return {
2806 |           content: [
2807 |             {
2808 |               type: "text",
2809 |               text: `Exported memories in ${format} format`,
2810 |             },
2811 |             {
2812 |               type: "text",
2813 |               text: exported,
2814 |             },
2815 |           ],
2816 |         };
2817 |       }
2818 | 
2819 |       case "memory_cleanup": {
2820 |         const daysToKeep =
2821 |           typeof args?.daysToKeep === "number" ? args.daysToKeep : 30;
2822 | 
2823 |         if (args?.dryRun) {
2824 |           const stats = await getMemoryStatistics();
2825 |           const cutoff = new Date(
2826 |             Date.now() - daysToKeep * 24 * 60 * 60 * 1000,
2827 |           );
2828 |           const oldCount = Object.entries(
2829 |             (stats as any).statistics?.byMonth || {},
2830 |           )
2831 |             .filter(([month]) => new Date(month + "-01") < cutoff)
2832 |             .reduce((sum, [_, count]) => sum + (count as number), 0);
2833 | 
2834 |           return {
2835 |             content: [
2836 |               {
2837 |                 type: "text",
2838 |                 text: `Dry run: Would delete approximately ${oldCount} memories older than ${daysToKeep} days`,
2839 |               },
2840 |             ],
2841 |           };
2842 |         } else {
2843 |           const deleted = await cleanupOldMemories(daysToKeep);
2844 |           return {
2845 |             content: [
2846 |               {
2847 |                 type: "text",
2848 |                 text: `Cleaned up ${deleted} old memories`,
2849 |               },
2850 |             ],
2851 |           };
2852 |         }
2853 |       }
2854 | 
2855 |       case "memory_intelligent_analysis": {
2856 |         const projectPath = args?.projectPath as string;
2857 |         const baseAnalysis = args?.baseAnalysis as any;
2858 | 
2859 |         // Get insights and similar projects
2860 |         const insights = await getProjectInsights(projectPath);
2861 |         const similar = await getSimilarProjects(baseAnalysis, 5);
2862 | 
2863 |         // Build intelligent analysis
2864 |         const intelligentAnalysis = {
2865 |           projectPath,
2866 |           contextualInsights: {
2867 |             insights: insights,
2868 |             similarProjects: similar.map((p: any) => ({
2869 |               name: p.projectPath,
2870 |               similarity: p.similarity,
2871 |               technologies: p.technologies,
2872 |               hasTests: p.hasTests,
2873 |               hasDocs: p.hasDocs,
2874 |             })),
2875 |             documentationHealth: {
2876 |               hasDocumentation: baseAnalysis?.documentation?.hasDocs || false,
2877 |               coverage: baseAnalysis?.documentation?.coverage || "unknown",
2878 |               recommendedImprovement: baseAnalysis?.documentation?.hasDocs
2879 |                 ? "Add missing documentation categories"
2880 |                 : "Create initial documentation structure",
2881 |             },
2882 |           },
2883 |           patterns: {
2884 |             technologyStack:
2885 |               baseAnalysis?.technologies?.primaryLanguage || "unknown",
2886 |             projectSize: baseAnalysis?.structure?.size || "unknown",
2887 |             testingMaturity: baseAnalysis?.structure?.hasTests
2888 |               ? "has tests"
2889 |               : "no tests",
2890 |             cicdMaturity: baseAnalysis?.structure?.hasCI
2891 |               ? "has CI/CD"
2892 |               : "no CI/CD",
2893 |           },
2894 |           predictions: {
2895 |             recommendedSSG:
2896 |               similar.length > 0
2897 |                 ? `Based on ${similar.length} similar projects`
2898 |                 : "Insufficient data",
2899 |             estimatedEffort:
2900 |               baseAnalysis?.structure?.size === "large"
2901 |                 ? "high"
2902 |                 : baseAnalysis?.structure?.size === "medium"
2903 |                   ? "medium"
2904 |                   : "low",
2905 |           },
2906 |           recommendations: [
2907 |             ...(baseAnalysis?.documentation?.hasDocs
2908 |               ? []
2909 |               : ["Create documentation structure using Diataxis framework"]),
2910 |             ...(baseAnalysis?.structure?.hasTests
2911 |               ? []
2912 |               : ["Add test coverage to improve reliability"]),
2913 |             ...(baseAnalysis?.structure?.hasCI
2914 |               ? []
2915 |               : ["Set up CI/CD pipeline for automated deployment"]),
2916 |           ],
2917 |         };
2918 | 
2919 |         return {
2920 |           content: [
2921 |             {
2922 |               type: "text",
2923 |               text: JSON.stringify(intelligentAnalysis, null, 2),
2924 |             },
2925 |           ],
2926 |         };
2927 |       }
2928 | 
2929 |       case "memory_enhanced_recommendation": {
2930 |         const projectPath = args?.projectPath as string;
2931 |         const baseRecommendation = args?.baseRecommendation as any;
2932 |         const projectFeatures = args?.projectFeatures as any;
2933 | 
2934 |         // Get historical deployment data and similar projects
2935 |         await getProjectInsights(projectPath);
2936 |         const similar = await getSimilarProjects(projectFeatures, 10);
2937 | 
2938 |         // Calculate success rates from similar projects
2939 |         const successfulDeployments = similar.filter(
2940 |           (p: any) => p.deploymentSuccess === true,
2941 |         );
2942 |         const ssgUsage: Record<string, number> = {};
2943 |         similar.forEach((p: any) => {
2944 |           if (p.recommendedSSG) {
2945 |             ssgUsage[p.recommendedSSG] = (ssgUsage[p.recommendedSSG] || 0) + 1;
2946 |           }
2947 |         });
2948 | 
2949 |         const enhancedRecommendation = {
2950 |           baseRecommendation: baseRecommendation?.ssg || "unknown",
2951 |           confidence: baseRecommendation?.confidence || 0,
2952 |           historicalContext: {
2953 |             similarProjectsAnalyzed: similar.length,
2954 |             successfulDeployments: successfulDeployments.length,
2955 |             successRate:
2956 |               similar.length > 0
2957 |                 ? (
2958 |                     (successfulDeployments.length / similar.length) *
2959 |                     100
2960 |                   ).toFixed(1) + "%"
2961 |                 : "N/A",
2962 |           },
2963 |           popularChoices: Object.entries(ssgUsage)
2964 |             .sort(([, a], [, b]) => (b as number) - (a as number))
2965 |             .slice(0, 3)
2966 |             .map(([ssg, count]) => ({
2967 |               ssg,
2968 |               usage: count,
2969 |               percentage:
2970 |                 similar.length > 0
2971 |                   ? (((count as number) / similar.length) * 100).toFixed(1) +
2972 |                     "%"
2973 |                   : "N/A",
2974 |             })),
2975 |           enhancedRecommendations: [
2976 |             {
2977 |               ssg: baseRecommendation?.ssg || "Jekyll",
2978 |               reason: "Base recommendation from analysis",
2979 |               confidence: baseRecommendation?.confidence || 0.7,
2980 |             },
2981 |             ...Object.entries(ssgUsage)
2982 |               .filter(([ssg]) => ssg !== baseRecommendation?.ssg)
2983 |               .slice(0, 2)
2984 |               .map(([ssg, count]) => ({
2985 |                 ssg,
2986 |                 reason: `Used by ${count} similar project(s)`,
2987 |                 confidence: similar.length > 0 ? count / similar.length : 0.5,
2988 |               })),
2989 |           ],
2990 |           considerations: [
2991 |             ...(projectFeatures.hasTests
2992 |               ? ["Project has tests - consider SSG with good test integration"]
2993 |               : []),
2994 |             ...(projectFeatures.hasCI
2995 |               ? ["Project has CI/CD - ensure SSG supports automated builds"]
2996 |               : []),
2997 |             ...(projectFeatures.complexity === "complex"
2998 |               ? ["Complex project - consider robust SSG with plugin ecosystem"]
2999 |               : []),
3000 |             ...(projectFeatures.isOpenSource
3001 |               ? ["Open source project - community support is important"]
3002 |               : []),
3003 |           ],
3004 |         };
3005 | 
3006 |         return {
3007 |           content: [
3008 |             {
3009 |               type: "text",
3010 |               text: JSON.stringify(enhancedRecommendation, null, 2),
3011 |             },
3012 |           ],
3013 |         };
3014 |       }
3015 | 
3016 |       case "memory_learning_stats": {
3017 |         const stats = await getMemoryStatistics();
3018 |         return {
3019 |           content: [
3020 |             {
3021 |               type: "text",
3022 |               text: JSON.stringify(
3023 |                 {
3024 |                   status: "active",
3025 |                   learningStats: stats,
3026 |                   message: "Learning stats from current memory system",
3027 |                 },
3028 |                 null,
3029 |                 2,
3030 |               ),
3031 |             },
3032 |           ],
3033 |         };
3034 |       }
3035 | 
3036 |       case "memory_knowledge_graph": {
3037 |         return {
3038 |           content: [
3039 |             {
3040 |               type: "text",
3041 |               text: JSON.stringify(
3042 |                 {
3043 |                   status: "development",
3044 |                   message: "Knowledge graph feature is being developed",
3045 |                   query: args?.query,
3046 |                 },
3047 |                 null,
3048 |                 2,
3049 |               ),
3050 |             },
3051 |           ],
3052 |         };
3053 |       }
3054 | 
3055 |       case "memory_contextual_search": {
3056 |         return {
3057 |           content: [
3058 |             {
3059 |               type: "text",
3060 |               text: JSON.stringify(
3061 |                 {
3062 |                   status: "development",
3063 |                   message: "Contextual search feature is being developed",
3064 |                   query: args?.query,
3065 |                   context: args?.context,
3066 |                 },
3067 |                 null,
3068 |                 2,
3069 |               ),
3070 |             },
3071 |           ],
3072 |         };
3073 |       }
3074 | 
3075 |       case "memory_agent_network": {
3076 |         return {
3077 |           content: [
3078 |             {
3079 |               type: "text",
3080 |               text: JSON.stringify(
3081 |                 {
3082 |                   status: "development",
3083 |                   message: "Agent network feature is being developed",
3084 |                   action: args?.action,
3085 |                 },
3086 |                 null,
3087 |                 2,
3088 |               ),
3089 |             },
3090 |           ],
3091 |         };
3092 |       }
3093 | 
3094 |       case "memory_pruning": {
3095 |         return {
3096 |           content: [
3097 |             {
3098 |               type: "text",
3099 |               text: JSON.stringify(
3100 |                 {
3101 |                   status: "development",
3102 |                   message: "Memory pruning feature is being developed",
3103 |                   dryRun: args?.dryRun,
3104 |                 },
3105 |                 null,
3106 |                 2,
3107 |               ),
3108 |             },
3109 |           ],
3110 |         };
3111 |       }
3112 | 
3113 |       case "memory_temporal_analysis": {
3114 |         return {
3115 |           content: [
3116 |             {
3117 |               type: "text",
3118 |               text: JSON.stringify(
3119 |                 {
3120 |                   status: "development",
3121 |                   message: "Temporal analysis feature is being developed",
3122 |                   query: args?.query,
3123 |                 },
3124 |                 null,
3125 |                 2,
3126 |               ),
3127 |             },
3128 |           ],
3129 |         };
3130 |       }
3131 | 
3132 |       case "memory_visualization": {
3133 |         return {
3134 |           content: [
3135 |             {
3136 |               type: "text",
3137 |               text: JSON.stringify(
3138 |                 {
3139 |                   status: "development",
3140 |                   message: "Memory visualization feature is being developed",
3141 |                   visualizationType: args?.visualizationType,
3142 |                 },
3143 |                 null,
3144 |                 2,
3145 |               ),
3146 |             },
3147 |           ],
3148 |         };
3149 |       }
3150 | 
3151 |       case "memory_export_advanced": {
3152 |         await initializeMemory();
3153 |         const manager = (await import("./memory/index.js")).getMemoryManager();
3154 |         if (!manager) throw new Error("Memory system not initialized");
3155 | 
3156 |         const result = await manager.export("json");
3157 |         return {
3158 |           content: [
3159 |             {
3160 |               type: "text",
3161 |               text: JSON.stringify(
3162 |                 {
3163 |                   status: "success",
3164 |                   exported: result.length,
3165 |                   data: result,
3166 |                 },
3167 |                 null,
3168 |                 2,
3169 |               ),
3170 |             },
3171 |           ],
3172 |         };
3173 |       }
3174 | 
3175 |       case "memory_import_advanced": {
3176 |         await initializeMemory();
3177 |         const manager = (await import("./memory/index.js")).getMemoryManager();
3178 |         if (!manager) throw new Error("Memory system not initialized");
3179 | 
3180 |         if (!args?.inputPath || typeof args.inputPath !== "string") {
3181 |           throw new Error("inputPath is required");
3182 |         }
3183 | 
3184 |         const fs = await import("fs/promises");
3185 |         const data = await fs.readFile(args.inputPath, "utf-8");
3186 |         const result = await manager.import(data, "json");
3187 |         return {
3188 |           content: [
3189 |             {
3190 |               type: "text",
3191 |               text: JSON.stringify(
3192 |                 {
3193 |                   status: "success",
3194 |                   imported: result,
3195 |                 },
3196 |                 null,
3197 |                 2,
3198 |               ),
3199 |             },
3200 |           ],
3201 |         };
3202 |       }
3203 | 
3204 |       case "memory_migration": {
3205 |         return {
3206 |           content: [
3207 |             {
3208 |               type: "text",
3209 |               text: JSON.stringify(
3210 |                 {
3211 |                   status: "development",
3212 |                   message: "Migration functionality not yet implemented",
3213 |                   action: args?.action,
3214 |                 },
3215 |                 null,
3216 |                 2,
3217 |               ),
3218 |             },
3219 |           ],
3220 |         };
3221 |       }
3222 | 
3223 |       case "memory_optimization_metrics": {
3224 |         const stats = await getMemoryStatistics();
3225 |         return {
3226 |           content: [
3227 |             {
3228 |               type: "text",
3229 |               text: JSON.stringify(
3230 |                 {
3231 |                   status: "active",
3232 |                   optimizationMetrics: stats,
3233 |                   message: "Optimization metrics from current memory system",
3234 |                 },
3235 |                 null,
3236 |                 2,
3237 |               ),
3238 |             },
3239 |           ],
3240 |         };
3241 |       }
3242 | 
3243 |       default:
3244 |         throw new Error(`Unknown tool: ${name}`);
3245 |     }
3246 |   } catch (error) {
3247 |     const errorMessage =
3248 |       error instanceof Error ? error.message : "Unknown error occurred";
3249 | 
3250 |     return formatMCPResponse({
3251 |       success: false,
3252 |       error: {
3253 |         code: "TOOL_EXECUTION_ERROR",
3254 |         message: errorMessage,
3255 |         details: error instanceof Error ? error.stack : undefined,
3256 |         resolution:
3257 |           "Check tool parameters and try again. If the issue persists, review server logs for details.",
3258 |       },
3259 |       metadata: {
3260 |         toolVersion: packageJson.version,
3261 |         executionTime: Date.now(),
3262 |         timestamp: new Date().toISOString(),
3263 |       },
3264 |     });
3265 |   }
3266 | });
3267 | 
3268 | // Start the server
3269 | async function main() {
3270 |   const transport = new StdioServerTransport();
3271 |   await server.connect(transport);
3272 | 
3273 |   // Show storage information at startup
3274 |   const storageDir =
3275 |     process.env.DOCUMCP_STORAGE_DIR || `${process.cwd()}/.documcp/memory`;
3276 |   console.error("DocuMCP server started successfully");
3277 |   console.error(`Storage location: ${storageDir}`);
3278 | }
3279 | 
3280 | main().catch((error) => {
3281 |   console.error("Failed to start DocuMCP server:", error);
3282 |   process.exit(1);
3283 | });
3284 | 
```
Page 28/29FirstPrevNextLast