mattrguerra/meridian-orders-mcpmainPrivate on GitHub, published here in full

getCustomers.ts

Language TypeScript2.1 KB54 lines

mcp-server/src/tools/getCustomers.ts

  1. import { z } from "zod";
  2. import type { ToolModule } from "./types.js";
  3. import { plinthRequest, type PlinthParams } from "../lib/http.js";
  4. import { toRequestDate } from "../lib/dates.js";
  5. /**
  6. * get_customers: customer records (Plinth method `customers.fetch`),
  7. * filterable by exact email or a signup/last-login date range.
  8. *
  9. * There is no phone filter: the API silently drops a phone param (fails open)
  10. * and returns the full customer list, so this tool must never accept one.
  11. * Output is not yet gated on verified identity (lib/classification.ts).
  12. *
  13. * Wire notes: no wrapper key; records keyed `cust_{ordinal}`. Phone formats
  14. * are inconsistent across records.
  15. */
  16. export const getCustomers: ToolModule = {
  17. name: "get_customers",
  18. config: {
  19. title: "Get customers",
  20. description:
  21. "Look up customer records by exact email or signup/last-login date range. Read-only. No phone lookup (fail-open).",
  22. inputSchema: {
  23. email: z.email().optional().describe("Exact-match email."),
  24. dateField: z.enum(["last_login", "signup"]).optional().describe("Default: signup."),
  25. fromDate: z.string().optional().describe("ISO YYYY-MM-DD; converted to yyyymmdd on the wire."),
  26. toDate: z.string().optional().describe("ISO YYYY-MM-DD; converted to yyyymmdd on the wire."),
  27. offset: z.number().int().min(0).optional(),
  28. limit: z.number().int().min(1).max(100).optional(),
  29. },
  30. },
  31. async handler(args, ctx) {
  32. const { email, dateField, fromDate, toDate, offset, limit } = args as {
  33. email?: string;
  34. dateField?: "last_login" | "signup";
  35. fromDate?: string;
  36. toDate?: string;
  37. offset?: number;
  38. limit?: number;
  39. };
  40. const params: PlinthParams = {
  41. email,
  42. date_field: dateField,
  43. since: fromDate !== undefined ? toRequestDate(fromDate) : undefined,
  44. until: toDate !== undefined ? toRequestDate(toDate) : undefined,
  45. offset,
  46. limit,
  47. };
  48. const body = await plinthRequest(ctx, "customers.fetch", params);
  49. return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
  50. },
  51. };