lithtrix_blob_search
Search parsed chunks semantically using natural-language queries. Control result count and similarity threshold for precise retrieval.
Instructions
GET /v1/blobs/search — semantic search over parsed chunks; shares quota with web search. Requires LITHTRIX_API_KEY.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | Natural-language query | |
| limit | No | Max hits (1–20) | |
| threshold | No | Minimum similarity (0–1) |
Implementation Reference
- tools/parse.js:163-181 (handler)Tool handler for lithtrix_blob_search: builds a GET /v1/blobs/search URL with query, optional limit, and optional threshold params; calls the Lithtrix API; returns JSON response.
async ({ q, limit, threshold }) => { const apiKey = process.env.LITHTRIX_API_KEY; if (!apiKey) return missingApiKeyResponse(); const url = new URL("/v1/blobs/search", LITHTRIX_API_URL); url.searchParams.set("q", q); if (limit !== undefined) url.searchParams.set("limit", String(limit)); if (threshold !== undefined) url.searchParams.set("threshold", String(threshold)); let response; try { response = await fetch(url.toString(), { headers: { Authorization: `Bearer ${apiKey}` }, }); } catch (err) { return networkErrorResponse(err); } return apiJsonResponse(response); } - tools/parse.js:153-161 (schema)Input schema for lithtrix_blob_search: requires 'q' (string 1-500 chars), optional 'limit' (int 1-20), optional 'threshold' (float 0-1).
{ q: z.string().min(1).max(500).describe("Natural-language query"), limit: z.number().int().min(1).max(20).optional().describe("Max hits (1–20)"), threshold: z .number() .min(0) .max(1) .optional() .describe("Minimum similarity (0–1)"), - tools/parse.js:150-182 (registration)Registration of lithtrix_blob_search via server.tool() with name, description, input schema, and handler.
server.tool( "lithtrix_blob_search", "GET /v1/blobs/search — semantic search over parsed chunks; shares quota with web search. Requires LITHTRIX_API_KEY.", { q: z.string().min(1).max(500).describe("Natural-language query"), limit: z.number().int().min(1).max(20).optional().describe("Max hits (1–20)"), threshold: z .number() .min(0) .max(1) .optional() .describe("Minimum similarity (0–1)"), }, async ({ q, limit, threshold }) => { const apiKey = process.env.LITHTRIX_API_KEY; if (!apiKey) return missingApiKeyResponse(); const url = new URL("/v1/blobs/search", LITHTRIX_API_URL); url.searchParams.set("q", q); if (limit !== undefined) url.searchParams.set("limit", String(limit)); if (threshold !== undefined) url.searchParams.set("threshold", String(threshold)); let response; try { response = await fetch(url.toString(), { headers: { Authorization: `Bearer ${apiKey}` }, }); } catch (err) { return networkErrorResponse(err); } return apiJsonResponse(response); } ); - tools/parse.js:17-30 (helper)Helper to return a missing API key error response.
function missingApiKeyResponse() { return { content: [ { type: "text", text: JSON.stringify({ error: "LITHTRIX_API_KEY environment variable is not set. " + "Register at https://lithtrix.ai and use lithtrix_register, then set the key.", }), }, ], isError: true, }; - tools/parse.js:47-74 (helper)Helper to parse API response JSON and return success/error MCP content.
async function apiJsonResponse(response) { let body; try { body = await response.json(); } catch { body = { message: `Invalid JSON (HTTP ${response.status})` }; } if (!response.ok) { return { content: [ { type: "text", text: JSON.stringify({ error: body.message ?? `Lithtrix API error (HTTP ${response.status})`, error_code: body.error_code ?? "UNKNOWN", status: body.status, }), }, ], isError: true, }; } return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }], }; }