mockzilla_docs_search
Search Mockzilla documentation by keyword to retrieve top-scoring sections with topic, heading, and snippet. Use this to verify syntax or features before answering.
Instructions
Search the mockzilla docs by keyword. Returns the top-scoring sections {topic, heading, snippet} so you can identify which topic to read in full. Use this BEFORE answering questions about mockzilla syntax, conventions, or features you're not 100% sure of — the docs are the source of truth, your training is not.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Free-text query, e.g. 'static directory layout'. | |
| limit | No |
Implementation Reference
- lib/docs.js:55-91 (handler)Handler function for mockzilla_docs_search. Tokenizes the query, iterates all doc topics, splits them into sections (by ## headings), scores each section, and returns the top-scoring results with topic, heading, snippet, and score.
export async function searchDocs(args) { const query = args.query; if (typeof query !== "string" || query.trim().length === 0) { throw new Error("`query` must be a non-empty string"); } const limit = Math.min(Math.max(parseInt(args.limit, 10) || 5, 1), 20); const tokens = tokenize(query); if (tokens.length === 0) { throw new Error("`query` produced no searchable tokens"); } const { topics } = await topicsList(); const sections = []; for (const topic of topics) { let text; try { text = await loadTopicText(topic); } catch { continue; // skip unreadable topics } sections.push(...sectionsOf(topic, text)); } const scored = sections .map((s) => ({ ...s, score: scoreSection(s, tokens) })) .filter((s) => s.score > 0) .sort((a, b) => b.score - a.score) .slice(0, limit) .map((s) => ({ topic: s.topic, heading: s.heading, snippet: snippetForQuery(s.body, tokens), score: s.score, })); return { query, results: scored }; } - lib/tools.js:285-310 (schema)Registration and input schema for mockzilla_docs_search. Defines the description, inputSchema (query as string, limit as integer 1-20 default 5), and maps to the searchDocs handler.
mockzilla_docs_search: { description: "Search the mockzilla docs by keyword. Returns the top-scoring " + "sections {topic, heading, snippet} so you can identify which " + "topic to read in full. Use this BEFORE answering questions about " + "mockzilla syntax, conventions, or features you're not 100% sure " + "of — the docs are the source of truth, your training is not.", inputSchema: { type: "object", properties: { query: { type: "string", description: "Free-text query, e.g. 'static directory layout'.", }, limit: { type: "integer", minimum: 1, maximum: 20, default: 5, }, }, required: ["query"], additionalProperties: false, }, handler: searchDocs, }, - lib/tools.js:19-19 (registration)The LOCAL_TOOLS object exported from lib/tools.js is the tool registration registry. It contains mockzilla_docs_search among other tools.
export const LOCAL_TOOLS = { - lib/docs.js:140-160 (helper)Helper to split markdown text into sections by ## headings. Used by searchDocs to create sections for scoring.
function sectionsOf(topic, text) { const lines = text.split("\n"); const sections = []; let current = { topic, heading: "(intro)", body: [] }; for (const line of lines) { const m = line.match(/^##+\s+(.*)$/); if (m) { if (current.body.length > 0 || current.heading !== "(intro)") { sections.push({ ...current, body: current.body.join("\n").trim() }); } current = { topic, heading: m[1].trim(), body: [] }; } else { current.body.push(line); } } if (current.body.length > 0 || current.heading !== "(intro)") { sections.push({ ...current, body: current.body.join("\n").trim() }); } return sections; } - lib/docs.js:196-210 (helper)Helper to extract a brief snippet (~3 lines) around the first line that matches any search token. Used by searchDocs for each result.
function snippetForQuery(body, tokens) { const lines = body.split("\n"); let bestIdx = 0; for (let i = 0; i < lines.length; i++) { const lower = lines[i].toLowerCase(); if (tokens.some((t) => lower.includes(t))) { bestIdx = i; break; } } const start = Math.max(0, bestIdx - 1); const end = Math.min(lines.length, bestIdx + 4); const snippet = lines.slice(start, end).join("\n").trim(); return snippet.length > 600 ? `${snippet.slice(0, 600)}…` : snippet; }