Skip to main content
Glama
elegroag

Backbone.js Documentation MCP Server

by elegroag

search-backbone

Search Backbone.js documentation chapters for specific text and retrieve relevant chapter links with matching excerpts.

Instructions

Busca texto en los capítulos Markdown y devuelve enlaces a los capítulos con coincidencias.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesTexto a buscar
caseSensitiveNoDistinguir mayúsculas/minúsculas
maxExcerptsNoNúmero de fragmentos por capítulo

Implementation Reference

  • The main handler function for the 'search-backbone' tool. It takes input arguments, calls searchResources from mcp-server, and formats search results into MCP content with introductory text and resource links to matching chapters.
    async (args) => {
        const query = args.query;
        const caseSensitive = args.caseSensitive;
        const maxExcerpts = args.maxExcerpts;
        const results = searchResources(query, { caseSensitive, maxExcerpts });
        if (!results.length) {
            return {
                content: [
                    { type: "text", text: `Sin coincidencias para "${query}".` }
                ]
            };
        }
    
        const content: Array<any> = [];
        content.push({ type: "text", text: `Coincidencias: ${results.length} capítulos para "${query}".` });
        for (const r of results) {
            content.push({
                type: "resource_link",
                uri: r.uri,
                name: `Capítulo ${String(r.chapter).padStart(2, '0')} — ${r.title}`,
                mimeType: r.mimeType,
                description: r.excerpts[0] ?? undefined,
            });
        }
    
        return { content };
    }
  • Zod-based input schema defining the parameters for the 'search-backbone' tool: required query string, optional case-sensitive flag, and max excerpts.
    {
        title: "Buscar en capítulos Backbone",
        description: "Busca texto en los capítulos Markdown y devuelve enlaces a los capítulos con coincidencias.",
        inputSchema: {
            query: z.string().min(2, 'La consulta debe tener al menos 2 caracteres').describe('Texto a buscar'),
            caseSensitive: z.boolean().optional().describe('Distinguir mayúsculas/minúsculas'),
            maxExcerpts: z.number().int().min(1).max(5).optional().describe('Número de fragmentos por capítulo'),
        }
    },
  • src/server.ts:65-103 (registration)
    MCP server registration of the 'search-backbone' tool, including name, schema, and handler function.
    server.registerTool(
        "search-backbone",
        {
            title: "Buscar en capítulos Backbone",
            description: "Busca texto en los capítulos Markdown y devuelve enlaces a los capítulos con coincidencias.",
            inputSchema: {
                query: z.string().min(2, 'La consulta debe tener al menos 2 caracteres').describe('Texto a buscar'),
                caseSensitive: z.boolean().optional().describe('Distinguir mayúsculas/minúsculas'),
                maxExcerpts: z.number().int().min(1).max(5).optional().describe('Número de fragmentos por capítulo'),
            }
        },
        async (args) => {
            const query = args.query;
            const caseSensitive = args.caseSensitive;
            const maxExcerpts = args.maxExcerpts;
            const results = searchResources(query, { caseSensitive, maxExcerpts });
            if (!results.length) {
                return {
                    content: [
                        { type: "text", text: `Sin coincidencias para "${query}".` }
                    ]
                };
            }
    
            const content: Array<any> = [];
            content.push({ type: "text", text: `Coincidencias: ${results.length} capítulos para "${query}".` });
            for (const r of results) {
                content.push({
                    type: "resource_link",
                    uri: r.uri,
                    name: `Capítulo ${String(r.chapter).padStart(2, '0')} — ${r.title}`,
                    mimeType: r.mimeType,
                    description: r.excerpts[0] ?? undefined,
                });
            }
    
            return { content };
        }
    );
  • Core search utility function that loads resources, performs regex-based text search on chapter contents, extracts contextual excerpts, counts matches per chapter, and returns sorted list of SearchMatch objects used by the tool handler.
    export const searchResources = (
        query: string,
        opts?: { caseSensitive?: boolean; maxExcerpts?: number }
    ): SearchMatch[] => {
        const q = (query ?? '').trim();
        if (!q) return [];
    
        loadResources();
    
        const escapeRegExp = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        const flags = opts?.caseSensitive ? 'g' : 'gi';
        const regex = new RegExp(escapeRegExp(q), flags);
        const maxExcerpts = Math.max(1, Math.min(10, opts?.maxExcerpts ?? 3));
    
        const matches: SearchMatch[] = [];
    
        for (const r of cachedResources) {
            const text = r.content.text ?? '';
            if (!text) continue;
    
            let occurrences = 0;
            const excerpts: string[] = [];
    
            let m: RegExpExecArray | null;
            while ((m = regex.exec(text)) !== null) {
                occurrences++;
                if (excerpts.length < maxExcerpts) {
                    const start = Math.max(0, m.index - 60);
                    const end = Math.min(text.length, m.index + m[0].length + 60);
                    const snippet = `${start > 0 ? '…' : ''}${text
                        .slice(start, end)
                        .replace(/\s+/g, ' ')
                        .trim()}${end < text.length ? '…' : ''}`;
                    excerpts.push(snippet);
                }
                if (regex.lastIndex === m.index) regex.lastIndex++; // evitar bucles con coincidencias vacías
            }
    
            if (occurrences > 0) {
                const chapter = r.metadata?.chapter ?? 0;
                const title = r.metadata?.title ?? `Capítulo ${chapter}`;
                const uri = `backbone://chapter/${String(chapter).padStart(2, '0')}`;
                matches.push({
                    chapter,
                    title,
                    uri,
                    mimeType: r.content.mimeType,
                    occurrences,
                    excerpts,
                });
            }
        }
    
        return matches.sort((a, b) => b.occurrences - a.occurrences);
    }
Install Server

Other Tools

Latest Blog Posts

MCP directory API

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

curl -X GET 'https://glama.ai/api/mcp/v1/servers/elegroag/backbone-mcp-server'

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