Skip to main content
Glama
pepesto-solutions

Pepesto MCP Server

Official

Pepesto Catalog (full SKU dump)

pepesto_catalog

Retrieve the full product catalog for a supermarket, including names, prices, images, and IDs. Use for market analysis or storefront builds; cache results to minimize API calls.

Instructions

Dump Pepesto's full indexed catalog for a supermarket (~1-2k SKUs of common cooking ingredients, with names, prices, images, IDs). Optionally pass a webhook_url to receive incremental updates on re-index. Use only when the user has explicitly asked for a catalog dump, market analysis, or storefront build; for normal recipe-to-cart flows use pepesto_oneshot or pepesto_products instead. Cache this query aggressively, no more than one call per day per supermarket is recommended. When presenting supermarket results the user, use the product key as (external) link to the supermarket product itself. Show image if available (json property image_url, don't search for external images, skip rendering the Pepesto image if the image has webp extesion)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
supermarket_domainYesSupermarket domain or ID, e.g. 'coop.ch', 'tesco.com', 'ah.nl'. See README for the full list.
webhook_urlNoURL to POST incremental catalog updates to.

Implementation Reference

  • The registerCatalogTool function registers the pepesto_catalog tool. The handler calls client.post('/catalog', args) via the runTool helper, which sends a POST request to the Pepesto API /catalog endpoint and wraps the response in a ToolResult (JSON stringified).
    export function registerCatalogTool(server: McpServer, client: PepestoClient): void {
      server.registerTool(
        "pepesto_catalog",
        {
          title: "Pepesto Catalog (full SKU dump)",
          description:
            "Dump Pepesto's full indexed catalog for a supermarket (~1-2k SKUs of common cooking " +
            "ingredients, with names, prices, images, IDs). Optionally pass a webhook_url to receive " +
            "incremental updates on re-index. Use only when the user has explicitly asked for a " +
            "catalog dump, market analysis, or storefront build; for normal recipe-to-cart flows " +
            "use pepesto_oneshot or pepesto_products instead. Cache this query aggressively, no more than " + 
            "one call per day per supermarket is recommended. When presenting supermarket results " + 
            "the user, use the product key as (external) link to the supermarket product itself. " + 
            "Show image if available (json property `image_url`, don't search for external images, " +
            "skip rendering the Pepesto image if the image has webp extesion)",
          inputSchema: {
            supermarket_domain: SupermarketDomain,
            webhook_url: z
              .string()
              .url()
              .optional()
              .describe("URL to POST incremental catalog updates to."),
          },
        },
        async (args) => runTool(() => client.post("/catalog", args)),
      );
  • SupermarketDomain is a Zod schema used as the inputSchema for the supermarket_domain parameter of pepesto_catalog. It validates a non-empty string describing a supermarket domain like 'coop.ch', 'tesco.com'.
    export const SupermarketDomain = z
      .string()
      .min(1)
      .describe(
        "Supermarket domain or ID, e.g. 'coop.ch', 'tesco.com', 'ah.nl'. See README for the full list.",
      );
  • src/server.ts:27-28 (registration)
    The pepesto_catalog tool is registered by calling registerCatalogTool(server, client) in the server creation function.
    registerCatalogTool(server, client);
    registerCreditsTool(server, client);
  • The runTool helper wraps the handler execution (client.post('/catalog', args)) in try/catch, formatting successful responses as JSON text and errors with descriptive messages.
    export async function runTool(fn: () => Promise<unknown>): Promise<ToolResult> {
      try {
        const result = await fn();
        return {
          content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
        };
      } catch (err) {
        const msg =
          err instanceof PepestoApiError
            ? err.message
            : err instanceof Error
            ? `Error: ${err.message}`
            : `Error: ${String(err)}`;
        return {
          content: [{ type: "text", text: msg }],
          isError: true,
        };
      }
    }
  • The PepestoClient.post method is the underlying HTTP client that sends the actual POST request to the Pepesto API at /catalog, handling auth, JSON serialization, and error wrapping.
      async post<T = unknown>(endpoint: string, body: unknown): Promise<T> {
        if (!this.apiKey) {
          throw new Error(
            "PEPESTO_API_KEY is not set. See the README (\"Getting an API key\") for how to " +
              "obtain one.",
          );
        }
        const path = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
        const url = `${this.baseUrl}${path}`;
    
        const headers: Record<string, string> = {
          "Content-Type": "application/json",
          Accept: "application/json",
          Authorization: `Bearer ${this.apiKey}`,
        };
    
        const res = await this.fetchImpl(url, {
          method: "POST",
          headers,
          body: JSON.stringify(body ?? {}),
        });
    
        const text = await res.text();
        if (!res.ok) {
          throw new PepestoApiError(res.status, path, text);
        }
        if (!text) {
          return {} as T;
        }
        try {
          return JSON.parse(text) as T;
        } catch {
          return text as unknown as T;
        }
      }
    }
Behavior4/5

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

No annotations provided, so description carries full burden. It discloses the optional webhook for incremental updates, caching advice, and image handling. Does not explicitly mention read-only nature or auth requirements, but covers key behaviors.

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

Conciseness4/5

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

Description is dense with useful information, front-loaded with purpose and core details. Slightly long but every sentence adds value. Could be slightly more concise, but well structured.

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

Completeness4/5

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

Covers return content (names, prices, images, IDs), caching, image handling, and presentation guidance. Lacks details on error handling or webhook format, but adequate for a dump tool.

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%, baseline 3. Description adds meaning: explains webhook_url is for incremental updates, and gives example for supermarket_domain. Adds value beyond schema.

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 dumps the full catalog for a supermarket with specific details (1-2k SKUs, names, prices, images, IDs). It distinguishes from siblings by mentioning alternative tools for normal recipe-to-cart flows.

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

Usage Guidelines5/5

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

Explicitly states when to use (catalog dump, market analysis, storefront build) and when not (use pepesto_oneshot or pepesto_products for normal flows). Also provides caching recommendations.

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/pepesto-solutions/pepesto-mcp'

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