#!/usr/bin/env node
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
import { createRagSearcher } from './rag/search.js';
import { DOCS_MCP_VERSION } from './version.js';
const searchSchema = z.object({
    packageName: z.enum(['@ceed/ads', '@ceed/cds']).describe('Package to search (@ceed/ads or @ceed/cds).'),
    query: z.string().min(1, 'Query text is required.'),
    topK: z
        .number()
        .int()
        .min(1)
        .max(100)
        .optional()
        .describe('Number of matches to return per page (default: 5, max: 100).'),
    page: z.number().int().min(1).optional().describe('Results page to fetch (default: 1).'),
});
const searchInputSchema = searchSchema.shape;
const formatSearchResult = (rank, result) => {
    const lines = [`#${rank + 1} (score: ${result.score.toFixed(3)})`, `source: ${result.metadata.source}`];
    if (result.metadata.heading) {
        lines.splice(1, 0, `heading: ${result.metadata.heading}`);
    }
    lines.push('', result.text.trim());
    return lines.join('\n');
};
export const createDocsMcpServer = () => {
    const server = new McpServer({
        name: '@ceed/docs-mcp',
        version: DOCS_MCP_VERSION,
    });
    const ragSearcher = createRagSearcher();
    server.registerTool('search', {
        title: 'Search documentation',
        description: 'Look up documentation chunks that best match the given query.',
        inputSchema: searchInputSchema,
    }, async (rawInput) => {
        const { packageName, query, topK, page } = searchSchema.parse(rawInput);
        const packageKey = packageName.split('/').pop() ?? undefined;
        try {
            const pageData = await ragSearcher.search(query, topK, packageKey, page);
            const { results, total, page: currentPage, pageSize, hasMore } = pageData;
            if (results.length === 0) {
                if (total === 0) {
                    return {
                        content: [
                            {
                                type: 'text',
                                text: 'No matching documentation found.',
                            },
                        ],
                    };
                }
                const totalPages = Math.max(1, Math.ceil(total / pageSize));
                return {
                    content: [
                        {
                            type: 'text',
                            text: `No results on page ${currentPage}. Try a page value between 1 and ${totalPages}.`,
                        },
                    ],
                };
            }
            const totalPages = Math.max(1, Math.ceil(total / pageSize));
            const startIndex = (currentPage - 1) * pageSize;
            const headerLines = [
                `Total matches: ${total}`,
                `Page ${currentPage} of ${totalPages} (page size ${pageSize})`,
            ];
            if (hasMore) {
                headerLines.push('More results available. Increase the page value to continue.');
            }
            const formatted = results
                .map((result, index) => formatSearchResult(startIndex + index, result))
                .join('\n\n---\n\n');
            const text = `${headerLines.join('\n')}\n\n${formatted}`;
            return {
                content: [
                    {
                        type: 'text',
                        text,
                    },
                ],
            };
        }
        catch (error) {
            const message = error instanceof Error ? error.message : 'Unknown search error';
            return {
                isError: true,
                content: [
                    {
                        type: 'text',
                        text: `Failed to search documentation index: ${message}`,
                    },
                ],
            };
        }
    });
    return server;
};
export const startDocsMcpServer = async () => {
    const server = createDocsMcpServer();
    const transport = new StdioServerTransport();
    await server.connect(transport);
};
startDocsMcpServer().catch((error) => {
    console.error('Failed to start @ceed/docs-mcp server:', error);
    process.exitCode = 1;
});
//# sourceMappingURL=server.js.map