Skip to main content
Glama
lithtrix

lithtrix-mcp

Official

lithtrix_feedback

Submit feedback signals (helpful, unhelpful, wrong) for search results or memory lookups using the reference type and ID from the response, stored to improve future routing.

Instructions

After lithtrix_search, send helpful / unhelpful / wrong signal using ref_type search_id and ref_id from the response _lithtrix.search_id (UUID). Same tool works for memory_key, blob_id, parse_id. Stored for future routing — no secrets or PII in note. Requires LITHTRIX_API_KEY.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ref_typeYesKind of reference
ref_idYesOpaque id (e.g. search UUID from _lithtrix.search_id, memory key, blob_id)
signalYesFeedback signal
noteNoOptional context, max 500 characters — no secrets or PII

Implementation Reference

  • The main handler function for lithtrix_feedback. Sends a feedback signal (helpful/unhelpful/wrong) to the Lithtrix API via POST /v1/feedback. Validates API key, builds request body with ref_type, ref_id, signal (and optional note), handles network/HTTP errors, and returns parsed response.
    async ({ ref_type, ref_id, signal, note }) => {
      const apiKey = process.env.LITHTRIX_API_KEY;
      if (!apiKey) {
        return {
          content: [
            {
              type: "text",
              text: JSON.stringify({
                error:
                  "LITHTRIX_API_KEY environment variable is not set. " +
                  "Register at https://lithtrix.ai to get an API key.",
              }),
            },
          ],
          isError: true,
        };
      }
    
      const url = new URL("/v1/feedback", LITHTRIX_API_URL);
      const body = { ref_type, ref_id, signal };
      if (note !== undefined && note !== "") {
        body.note = note;
      }
    
      let response;
      try {
        response = await fetch(url.toString(), {
          method: "POST",
          headers: {
            Authorization: `Bearer ${apiKey}`,
            "Content-Type": "application/json",
          },
          body: JSON.stringify(body),
        });
      } catch (err) {
        return {
          content: [
            {
              type: "text",
              text: JSON.stringify({
                error: `Network error contacting Lithtrix API: ${err.message}`,
              }),
            },
          ],
          isError: true,
        };
      }
    
      const text = await response.text();
      let parsed;
      try {
        parsed = JSON.parse(text);
      } catch {
        parsed = { message: text || `HTTP ${response.status}` };
      }
    
      if (!response.ok) {
        return {
          content: [
            {
              type: "text",
              text: JSON.stringify({
                error: parsed.message ?? `Lithtrix API error (HTTP ${response.status})`,
                error_code: parsed.error_code ?? "UNKNOWN",
              }),
            },
          ],
          isError: true,
        };
      }
    
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(parsed, null, 2),
          },
        ],
      };
    }
  • Zod schema defining the input parameters: ref_type (enum: search_id, memory_key, blob_id, parse_id, browse_id), ref_id (min 1 char), signal (helpful/unhelpful/wrong), and optional note (max 500 chars).
    {
      ref_type: z
        .enum(["search_id", "memory_key", "blob_id", "parse_id", "browse_id"])
        .describe("Kind of reference"),
      ref_id: z
        .string()
        .min(1)
        .describe("Opaque id (e.g. search UUID from _lithtrix.search_id, memory key, blob_id)"),
      signal: z.enum(["helpful", "unhelpful", "wrong"]).describe("Feedback signal"),
      note: z
        .string()
        .max(500)
        .optional()
        .describe("Optional context, max 500 characters — no secrets or PII"),
    },
  • Exported registerFeedbackTool function that registers 'lithtrix_feedback' as a named MCP tool with description and schema on the server instance.
    export function registerFeedbackTool(server) {
      server.tool(
        "lithtrix_feedback",
        "After lithtrix_search, send helpful / unhelpful / wrong signal using ref_type search_id and " +
          "ref_id from the response _lithtrix.search_id (UUID). Same tool works for memory_key, blob_id, " +
          "parse_id. Stored for future routing — no secrets or PII in note. Requires LITHTRIX_API_KEY.",
        {
          ref_type: z
            .enum(["search_id", "memory_key", "blob_id", "parse_id", "browse_id"])
            .describe("Kind of reference"),
          ref_id: z
            .string()
            .min(1)
            .describe("Opaque id (e.g. search UUID from _lithtrix.search_id, memory key, blob_id)"),
          signal: z.enum(["helpful", "unhelpful", "wrong"]).describe("Feedback signal"),
          note: z
            .string()
            .max(500)
            .optional()
            .describe("Optional context, max 500 characters — no secrets or PII"),
        },
        async ({ ref_type, ref_id, signal, note }) => {
          const apiKey = process.env.LITHTRIX_API_KEY;
          if (!apiKey) {
            return {
              content: [
                {
                  type: "text",
                  text: JSON.stringify({
                    error:
                      "LITHTRIX_API_KEY environment variable is not set. " +
                      "Register at https://lithtrix.ai to get an API key.",
                  }),
                },
              ],
              isError: true,
            };
          }
    
          const url = new URL("/v1/feedback", LITHTRIX_API_URL);
          const body = { ref_type, ref_id, signal };
          if (note !== undefined && note !== "") {
            body.note = note;
          }
    
          let response;
          try {
            response = await fetch(url.toString(), {
              method: "POST",
              headers: {
                Authorization: `Bearer ${apiKey}`,
                "Content-Type": "application/json",
              },
              body: JSON.stringify(body),
            });
          } catch (err) {
            return {
              content: [
                {
                  type: "text",
                  text: JSON.stringify({
                    error: `Network error contacting Lithtrix API: ${err.message}`,
                  }),
                },
              ],
              isError: true,
            };
          }
    
          const text = await response.text();
          let parsed;
          try {
            parsed = JSON.parse(text);
          } catch {
            parsed = { message: text || `HTTP ${response.status}` };
          }
    
          if (!response.ok) {
            return {
              content: [
                {
                  type: "text",
                  text: JSON.stringify({
                    error: parsed.message ?? `Lithtrix API error (HTTP ${response.status})`,
                    error_code: parsed.error_code ?? "UNKNOWN",
                  }),
                },
              ],
              isError: true,
            };
          }
    
          return {
            content: [
              {
                type: "text",
                text: JSON.stringify(parsed, null, 2),
              },
            ],
          };
        }
      );
  • index.js:50-52 (registration)
    Registration call in the main index.js: registerFeedbackTool(server) imports and invokes the registration function.
    registerFeedbackTool(server);
    registerBrowseTool(server);
    registerCommonsTool(server);
  • Environment variable default for Lithtrix API URL, defaults to 'https://lithtrix.ai'.
    const LITHTRIX_API_URL = process.env.LITHTRIX_API_URL ?? "https://lithtrix.ai";
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It discloses that notes are stored for routing, advises against secrets/PII, and mentions the required API key. However, it does not explicitly state whether the tool is idempotent or what side effects occur (e.g., overwriting previous feedback).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loading the core action and then adding essential context. Every phrase serves a purpose, with no redundancy or extraneous information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple feedback tool with no output schema, the description covers purpose, usage, parameter details, authentication, and safety constraints. It is complete for an agent to use correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds significant value beyond the schema. It explains where to get the ref_id (from _lithtrix.search_id), provides concrete examples for ref_type, and clarifies constraints on note (max 500, no secrets). This helps an agent correctly construct parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: sending helpful/unhelpful/wrong signals using a ref_type and ref_id from specific sources like lithtrix_search response. It specifically mentions the verb 'send' and resource 'feedback signal', and distinguishes from sibling tools that handle blobs, memory, etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides usage context: 'After lithtrix_search' and that the same tool works for other ref_types. It does not explicitly state when not to use or list alternatives, but the context is clear enough for an agent to infer appropriate usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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/lithtrix/lithtrix-mcp'

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