#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
ErrorCode,
McpError
} from '@modelcontextprotocol/sdk/types.js';
import {
analyzeCodebase,
AnalyzeCodebaseSchema
} from './tools/analyze-codebase.js';
import {
generateDocumentation,
GenerateDocumentationSchema
} from './tools/generate-documentation.js';
import {
detectMissingDocs,
DetectMissingDocsSchema
} from './tools/detect-missing-docs.js';
import {
suggestImprovements,
SuggestImprovementsSchema
} from './tools/suggest-improvements.js';
// Create server instance
const server = new Server(
{
name: 'smart-docs-mcp',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
// Tool definitions
const TOOLS = [
{
name: 'analyze_codebase',
description: 'Analyze a codebase or file to extract code elements and calculate documentation coverage. Supports TypeScript, JavaScript, and Python.',
inputSchema: AnalyzeCodebaseSchema
},
{
name: 'generate_documentation',
description: 'Generate comprehensive markdown documentation for a codebase or file, including all code elements and their existing documentation.',
inputSchema: GenerateDocumentationSchema
},
{
name: 'detect_missing_docs',
description: 'Detect code elements that are missing documentation and categorize them by severity (critical, medium, low).',
inputSchema: DetectMissingDocsSchema
},
{
name: 'suggest_improvements',
description: 'Analyze existing documentation and suggest improvements, including templates for missing docs and enhancements for incomplete documentation.',
inputSchema: SuggestImprovementsSchema
}
];
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: TOOLS.map(tool => ({
name: tool.name,
description: tool.description,
inputSchema: {
type: 'object',
properties: Object.entries(tool.inputSchema.shape).reduce((acc, [key, value]) => {
acc[key] = {
type: value._def.typeName.toLowerCase().replace('zod', ''),
description: value._def.description || ''
};
return acc;
}, {} as Record<string, any>)
}
}))
};
});
// Handle tool execution
server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
const { name, arguments: args } = request.params;
switch (name) {
case 'analyze_codebase': {
const validated = AnalyzeCodebaseSchema.parse(args);
const result = await analyzeCodebase(validated);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
};
}
case 'generate_documentation': {
const validated = GenerateDocumentationSchema.parse(args);
const result = await generateDocumentation(validated);
return {
content: [
{
type: 'text',
text: result.success ? result.documentation : JSON.stringify(result, null, 2)
}
]
};
}
case 'detect_missing_docs': {
const validated = DetectMissingDocsSchema.parse(args);
const result = await detectMissingDocs(validated);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
};
}
case 'suggest_improvements': {
const validated = SuggestImprovementsSchema.parse(args);
const result = await suggestImprovements(validated);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
};
}
default:
throw new McpError(
ErrorCode.MethodNotFound,
`Unknown tool: ${name}`
);
}
} catch (error) {
if (error instanceof McpError) {
throw error;
}
throw new McpError(
ErrorCode.InternalError,
`Tool execution failed: ${(error as Error).message}`
);
}
});
// Start server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('Smart Docs MCP Server running on stdio');
}
main().catch((error) => {
console.error('Fatal error in main():', error);
process.exit(1);
});