Bygge en MCP-server for WooCommerce: en praktisk guide

Bygge en MCP-server for WooCommerce: en praktisk guide

Sist verifisert: 22. september 2026
8 min lesetid
Guide
500+ WP-prosjekter
AI-integrasjon

#Bygge en MCP-server for WooCommerce: en praktisk guide

Model Context Protocol gir en KI-agent en typet, introspekterbar flate å handle mot butikken på. WooCommerce har allerede et REST API under /wp-json/wc/v3/. Setter du MCP foran det, blir denne flaten noe en LLM kan kalle uten å gjette parameternavn. Det er arkitekturen jeg ruller ut for kunder som vil ha katalogen og ordreintensjonen tilgjengelig fra Claude, ChatGPT eller sin egen agent-runtime.

Artikkelen hører til tjenesten utvikling av MCP-servere og søylen Universal Commerce Protocol.

#TL;DR

  • MCP ligger foran WooCommerce REST som en typet JSON-RPC-flate.
  • Tre verktøy dekker det meste agenten trenger: catalogue.list, product.detail, order.intent.
  • Zod-skjemaer definerer hver inn- og utdata og kjører ved hvert kall.
  • Map WooCommerce-felter til schema.org Product og Offer, slik at agentens svar blir konsistente på tvers av flater.
  • Cloudflare Workers er mitt standardvalg for utrulling av MCP-servere som domineres av lesing.

#Hva MCP egentlig er

Anthropic lanserte Model Context Protocol 25. november 2024 (anthropic.com/news/model-context-protocol). Det er en åpen protokoll basert på JSON-RPC 2.0 som lar en klient (en LLM-vert som Claude Desktop, en IDE eller din egen agent-runtime) snakke med en server (din MCP-implementasjon) over stdio eller HTTP med Server-Sent Events.

Tre primitiver:

  • Tools. Kallbare funksjoner med typet inn- og utdata. Agenten velger én og kaller den.
  • Resources. Lesbare referanser til dokumenter eller poster som agenten kan hente inn i konteksten.
  • Prompts. Promptmaler levert av serveren, som verten kan kalle.

For en WooCommerce-butikk er det tools som bærer hovedtyngden. Å bla i katalogen er et verktøykall. Produktdetaljer er et verktøykall. Å foreslå en ordre er et verktøykall. Resources er nyttige når agenten trenger hele teksten i returvilkårene eller en lang produktbeskrivelse; prompts er nyttige når du vil levere ferdige interaksjoner (“foreslå tre produkter for denne kundeprofilen”).

#Hvilke MCP-verktøy en WooCommerce-butikk trenger

Før jeg skriver en eneste kodelinje, lister jeg opp intensjonene agenten skal kunne uttrykke overfor butikken. For en typisk WooCommerce-butikk er listen kort:

  1. Bla i katalogen med filtre (catalogue.list).
  2. Fullstendige detaljer om ett produkt (product.detail).
  3. Foreslå en ordre på vegne av kunden, returnert som et utkast som et menneske bekrefter (order.intent).
  4. Sjekke statusen til en eksisterende ordre ut fra ordrenummer og e-postadresse (order.status).
  5. Spørre etter lagerbeholdning for en SKU (inventory.check).

Hver intensjon tilsvarer nøyaktig ett verktøy. Motstå fristelsen til å eksponere wc.products.get, wc.products.list, wc.orders.create som én-til-én-innpakning av REST. Agenten har ingen nytte av REST-verb; den har nytte av intensjonsverb.

#Slik definerer du MCP-verktøy i Zod

TypeScript-SDK-en i @modelcontextprotocol/sdk bruker Zod (zod.dev) til inn- og utdataskjemaer. Slik ser kontrakten for catalogue.list ut:

import { z } from "zod";

export const catalogueListInput = z.object({
  query: z.string().min(2).max(200).optional(),
  category: z.string().optional(),
  in_stock: z.boolean().optional(),
  price_min: z.number().nonnegative().optional(),
  price_max: z.number().nonnegative().optional(),
  page: z.number().int().min(1).max(100).default(1),
  per_page: z.number().int().min(1).max(50).default(12),
});

export const catalogueListOutput = z.object({
  results: z.array(
    z.object({
      sku: z.string(),
      name: z.string(),
      url: z.string().url(),
      price: z.object({
        amount: z.number().nonnegative(),
        currency: z.string().length(3),
      }),
      availability: z.enum(["InStock", "OutOfStock", "PreOrder"]),
      image: z.string().url().optional(),
    })
  ),
  total: z.number().int().nonnegative(),
  page: z.number().int(),
});

To ting er viktige her. For det første bruker utdataene schema.org-vokabularet (InStock, OutOfStock, PreOrder er verdier rett fra ItemAvailability). For det andre avviser inndataene søppel ved protokollgrensen; handleren ser aldri query: "" eller en negativ price_min.

Hvert verktøy deklarerer jeg etter samme mønster: inndataskjema, utdataskjema, handler. Handleren er en tynn adapter over /wp-json/wc/v3/. Zod kjører to ganger per kall: én gang på inndata, én gang på utdata. Sjekken av utdata fanger handlerfeil som ellers ville lekket til agenten som misdannede data.

#Slik kobler du MCP-serveren til WooCommerce REST API

Handleren for catalogue.list leser fra /wp-json/wc/v3/products:

async function handleCatalogueList(input: z.infer<typeof catalogueListInput>) {
  const params = new URLSearchParams();
  if (input.query) params.set("search", input.query);
  if (input.category) params.set("category", input.category);
  if (input.in_stock) params.set("stock_status", "instock");
  if (input.price_min !== undefined) params.set("min_price", String(input.price_min));
  if (input.price_max !== undefined) params.set("max_price", String(input.price_max));
  params.set("page", String(input.page));
  params.set("per_page", String(input.per_page));

  const response = await fetch(
    `${WC_BASE}/wp-json/wc/v3/products?${params.toString()}`,
    { headers: { Authorization: `Basic ${WC_AUTH}` } }
  );

  const products = await response.json();
  const total = Number(response.headers.get("X-WP-Total") ?? 0);

  return catalogueListOutput.parse({
    results: products.map(mapWooProductToSchemaOrg),
    total,
    page: input.page,
  });
}

Hjelpefunksjonen mapWooProductToSchemaOrg oversetter WooCommerce-feltnavn (stock_status, regular_price, permalink) til den schema.org-kompatible formen fra utdatadeklarasjonen. Feltmappingen ligger på ett sted, kalles fra ett verktøy, som kalles fra én handler. Avvik mellom WooCommerce-oppdateringer og agentkontrakten fanges av parse-kallet på utdata, ikke av produksjon.

I order.intent kaller jeg aldri WooCommerce sine skrivende endepunkter fra handleren. Verktøyet returnerer et ordreutkast som verten viser brukeren, brukeren bekrefter, og først da kaller en separat, autentisert vei POST /wp-json/wc/v3/orders. Å skrive i blinde på grunnlag av en LLM er en dårlig standard. Det passer også med GDPR art. 25 (innebygd personvern); utkastet lar deg tilpasse kjøpsknappen og markedsføringssamtykkene før operasjonen utføres.

#Slik mapper du WooCommerce-felter til schema.org

To grunner til å holde verktøyenes utdata i schema.org-vokabularet:

Agenter bruker de samme ordene på tvers av kilder. Når en agent svarer på “er dette produktet tilgjengelig?”, syr den sammen en Product-entitet fra MCP-serveren din, en Offer med availability og eventuelt en Review. Hvis MCP-serveren din returnerer { "stock": "ja" } og en annen kilde availability: "https://schema.org/InStock", må agenten forene to vokabularer. Med schema.org-samsvar på din side slipper den det.

Butikkens strukturerte data snakker uansett schema.org. Din /wp-content/themes/<theme>/single-product.php (eller den headless-ekvivalenten) sender ut JSON-LD av typen Product. Holder du MCP-utdataene i samme form, serverer den samme produktsiden de samme dataene til Googles crawler, til OpenAIs crawler via URL og til agenten som kaller MCP-verktøyet ditt direkte.

Mappingen av et typisk WooCommerce-produkt ser slik ut:

WooCommerce-feltschema.org-felt
skusku
namename
permalinkurl
regular_price + currencyoffers.price + priceCurrency
stock_status: "instock"availability: InStock
stock_status: "outofstock"availability: OutOfStock
images[0].srcimage
descriptiondescription

Varianter krever et ekstra lag (en hasVariant-liste av typen Product), men grunnformen er den samme.

#Slik gjør du ordrer idempotente i MCP-serveren

Leseverktøyene (catalogue.list, product.detail, inventory.check, order.status) er naturlig idempotente. Tre kall gir samme svar.

order.intent er fellen. Agenten kan kalle to ganger hvis nettverket mellom svaret og verten hikker. Kontrakten jeg ruller ut:

  • order.intent tar imot en valgfri idempotency_key (UUID levert av verten).
  • Handleren lagrer nøkkelen i Workers KV med TTL på 24 timer, sammen med ID-en til ordreutkastet som ble opprettet.
  • Et nytt kall med samme nøkkel returnerer det samme utkastet i stedet for å lage et nytt.

Mønsteret tilsvarer Stripes idempotens på POST /v1/charges. Det er godt forstått; agenter og mennesker har like stor nytte av det.

#Slik ruller du ut MCP-serveren på Cloudflare Workers

TypeScript-SDK-en for MCP eksporterer klassen Server pluss transportadaptere. For Workers bruker jeg strømmende HTTP-transport. Inngangen til Workeren ser slik ut:

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.method !== "POST") {
      return new Response("Method not allowed", { status: 405 });
    }

    const auth = request.headers.get("Authorization");
    if (!isValidAgentToken(auth, env)) {
      return new Response("Unauthorized", { status: 401 });
    }

    const server = createWooCommerceMcpServer(env);
    const transport = new StreamableHTTPServerTransport(request);
    return server.connect(transport);
  },
};

isValidAgentToken sjekker avgrensede tokens i Workers KV. Skrivebeskyttede verktøy slipper gjennom med et token med lavere rettigheter; order.intent krever et token med scope orders:write. Autentiseringsstrategien er ett av to mønstre for MCP-autentisering.

wrangler.toml deklarerer origin-URL-en til WordPress, forbrukernøkkelen og hemmeligheten for WooCommerce (som Worker-hemmeligheter, aldri i koden) og et KV-navnerom for idempotens. Utrulling skjer med wrangler deploy. Workeren holder seg liten (godt under grensen på 1 MB komprimert bundle), fordi den bare er JSON-RPC-ruting pluss REST-adaptere.

#Slik logger og overvåker du MCP-verktøykall

Hvert verktøykall logger jeg med:

  • Navnet på verktøyet.
  • En SHA-256-hash av inndataene (ikke selve inndataene; risiko for personopplysninger etter GDPR art. 32).
  • Forsinkelse.
  • Om valideringen av utdata gikk gjennom eller ikke.
  • Scopet til agentens token.

Loggene går via Cloudflare Logpush til langtidslagring. To driftsvaner dette gjør mulig:

Innstramming av skjemaer. Seks uker etter lansering går jeg gjennom valideringsfeilene. Hver utdatafeil er en handlerfeil eller et WooCommerce-felt som ikke er mappet. Hver inndatafeil er enten en agent med en svakhet eller et for strengt skjema. Begge deler havner i neste utgivelse.

Kostnadsfordeling. Verktøykall er målbar belastning på WooCommerce-origin. Loggen viser hvilket agenttoken som skaper belastningen, og med hvilket verktøy. En enkelt agent som oppfører seg dårlig og går i loop på catalogue.list, er én loggspørring unna å bli identifisert.

#Andre guider om MCP og WooCommerce

Denne artikkelen viser selve implementeringen. En feiltolerant arkitektur for ERP-synkronisering, Redis-køer og databasetransaksjoner er beskrevet i vår guide til arkitektur for integrasjon mellom WooCommerce og ERP 2026. Tjenestesiden er utvikling av MCP-servere. Den bredere strategien finner du i Universal Commerce Protocol.

Prisen er individuell, fordi omfanget avhenger av hvor mange verktøy du trenger, hvor komplekse WooCommerce-utvidelsene er og hvilke agent-runtimes du vil støtte.

Neste steg

Gjør artikkelen om til faktisk implementering

Denne blokken styrker intern lenking og sender leseren videre til de mest relevante tjenestene og innholdet.

Vil du få dette implementert på nettstedet ditt?

Hvis du planlegger headless WordPress, frikoblet frontend eller migrering til Astro, kan jeg bygge arkitektur, API og frontend.

Relevant klynge

Utforsk andre WordPress-tjenester og kunnskapsbase

Styrk virksomheten din med profesjonell teknisk støtte innen kjerneområdene i WordPress-økosystemet.

Artikkel-FAQ

Ofte stilte spørsmål

Praktiske svar for å bruke temaet i faktisk arbeid.

SEO-readyGEO-readyAEO-ready5 Q&A
Hva er MCP, og hvorfor bruke det med WooCommerce?#
Model Context Protocol er en JSON-RPC-basert protokoll som Anthropic lanserte 25. november 2024 for å koble KI-agenter til data og verktøy. En MCP-server foran WooCommerce gir agenten typede handlinger som catalogue.list og order.intent, i stedet for å tvinge den til å gjette hvilket /wp-json/wc/v3/-endepunkt den skal kalle.
Erstatter MCP WooCommerce REST API?#
Nei. MCP ligger foran REST API-et. Under panseret kaller verktøyhandlerne fortsatt /wp-json/wc/v3/. REST forblir sannhetskilden. MCP er den typede flaten som en LLM-agent kan introspektere og kalle uten manuell promptutvikling.
Hvor ligger verktøydefinisjonene?#
I koden, ved siden av serveren. Hvert verktøy har et navn, et inndataskjema i Zod, et utdataskjema i Zod og en handler. MCP-SDK-en eksponerer tools/list for klientene, slik at agenten ved kjøretid oppdager hva som kan kalles.
Hvorfor Cloudflare Workers og ikke en Node-server?#
Workers gir global tilstedeværelse på edge, liten angrepsflate og en prismodell som passer agentens ujevne trafikk. TypeScript-SDK-en for MCP kjører på webplattform-API-ene som Workers tilbyr; ingen node-only-moduler trengs.
Hvordan autentiserer agenten seg mot MCP-serveren?#
For skrivebeskyttede verktøy holder det ofte med en transport uten autentisering pluss en liste over tillatte IP-adresser. For order.intent og alle verktøy som endrer tilstand: et avgrenset API-token utstedt av butikken og sjekket ved hver forespørsel. Hele mønsteret er beskrevet i guiden om autentiseringsmønstre for MCP.

Trenger du FAQ tilpasset bransje og marked? Vi lager en versjon som støtter dine forretningsmål.

Ta kontakt

Relaterte artikler