Skip to main content
Glama
bbwrl

Shopping List MCP Server

by bbwrl

Shopping List App

Eine einfache Einkaufslisten-App, erstellt mit Next.js 15 (App Router). Jedes Produkt gehört zu einer Person, kann als gekauft markiert und gelöscht werden.

Dieses Projekt ist bewusst klein gehalten – es ist ein Lern-/Übungsprojekt für IMS Praxis 5.

Funktionen

  • Produkte hinzufügen, als gekauft markieren, löschen

  • Nach Person filtern

  • Persistenz über eine einfache JSON-Datei (kein Datenbankserver erforderlich)

  • Drei Arten, mit den Daten zu arbeiten:

    • Server Actions – werden direkt vom Frontend verwendet (src/app/actions.ts)

    • REST-API – verfügbar unter /api/products, z. B. für externe Clients oder curl

    • MCP-Server – stellt dieselben Daten als MCP-Tools bereit (z. B. für ChatGPT), indem er die REST-API aufruft

Related MCP server: LystBot

Technologie-Stack

  • Next.js 15 / React 19, App Router

  • TypeScript

  • Keine Datenbank, kein ORM – Persistenz über eine JSON-Datei (data/products.json)

  • MCP TypeScript SDK via mcp-handler, mit Streamable HTTP Transport

Erste Schritte

npm install
npm run dev

Öffnen Sie die App unter http://localhost:3000.

Für den lokalen Betrieb ist keine Konfiguration oder .env-Datei erforderlich. Siehe Umgebungsvariablen für die eine optionale Einstellung, die vom MCP-Server verwendet wird.

Projektstruktur

src/
  app/
    page.tsx            # Home page (Server Component), loads products server-side
    actions.ts           # Server Actions: addProductAction, togglePurchasedAction, deleteProductAction
    api/
      products/
        route.ts          # GET /api/products, POST /api/products
        [id]/route.ts      # GET/PATCH/DELETE /api/products/:id
      [transport]/
        route.ts          # MCP endpoint (Streamable HTTP), served at /api/mcp
  components/
    ProductForm.tsx        # Add-product form (uses a Server Action)
    ProductList.tsx        # List incl. toggle/delete (uses Server Actions)
  lib/
    productRepository.ts   # the only place that touches the filesystem (data/products.json)
    mcp/
      server.ts             # registers the MCP tools
      shoppingApiClient.ts   # MCP's only way to reach the data — calls the REST API, never the repository directly
  types/
    product.ts             # Product type

data/
  products.json            # data store (created automatically if missing)

Datenmodell

interface Product {
  id: string;
  name: string;
  person: string;
  purchased: boolean;
  createdAt: string; // ISO date
}

Persistenz

Alle Produkte befinden sich in data/products.json. Der gesamte Dateizugriff ist in src/lib/productRepository.ts gekapselt – weder die UI noch die API-Routen lesen oder schreiben die Datei direkt. Das Repository stellt bereit:

getProducts()
getProductsByPerson(person)
getProductById(id)
addProduct(product)
updateProduct(id, changes)
deleteProduct(id)

Hinweis: Diese dateibasierte Persistenz ist bewusst nur eine Prototyp-/Entwicklungslösung. Auf Vercel (und anderen serverlosen Plattformen) ist das lokale Dateisystem nicht zuverlässig persistent über mehrere Anfragen oder Deployments hinweg – Schreibvorgänge können verloren gehen. Für den Produktionseinsatz sollte productRepository.ts durch eine echte, persistente Datenbank ersetzt werden (z. B. Turso). Da der Rest der App (UI, Server Actions, API-Routen) nur über die exportierten Repository-Funktionen mit den Daten spricht, betrifft dieser Austausch nur diese eine Datei.

Frontend ↔ Backend

Das Frontend (page.tsx, ProductForm, ProductList) verwendet Next.js Server Actions (src/app/actions.ts), um Produkte zu erstellen, zu aktualisieren und zu löschen. Es gibt keinen fetch-Aufruf im Client – die Server Actions rufen das Repository direkt auf und lösen dann eine Aktualisierung der servergerenderten Daten mittels revalidatePath("/") aus.

Die REST-API unter /api/products ist unabhängig und kann separat verwendet werden (z. B. von externen Tools, Skripten oder zum Testen) – sie liest und schreibt dieselbe Datenquelle.

REST-API

Produkte lesen

GET /api/products
GET /api/products?person=Rinaldo   # filter by person, case-insensitive
GET /api/products/:id

Ein Produkt hinzufügen

POST /api/products
Content-Type: application/json

{ "name": "Milk", "person": "Rinaldo" }

id, purchased (false) und createdAt werden automatisch gesetzt.

Ein Produkt aktualisieren

PATCH /api/products/:id
Content-Type: application/json

{ "purchased": true }

Es müssen nicht alle Felder angegeben werden (name, person, purchased sind jeweils optional und unabhängig aktualisierbar).

Ein Produkt löschen

DELETE /api/products/:id

Fehlerantworten

{ "error": "Product not found" }

Fall

Status

Ungültige/leere Anfrage

400

Unbekannte ID

404

Interner Fehler

500

curl-Beispiele

# Add a product
curl -X POST http://localhost:3000/api/products \
  -H "Authorization: Bearer $SHOPPING_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Milk","person":"Rinaldo"}'

# List a person's products
curl "http://localhost:3000/api/products?person=Rinaldo" \
  -H "Authorization: Bearer $SHOPPING_API_KEY"

# Mark a product as purchased
curl -X PATCH http://localhost:3000/api/products/PRODUCT_ID \
  -H "Authorization: Bearer $SHOPPING_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"purchased":true}'

# Delete a product
curl -X DELETE http://localhost:3000/api/products/PRODUCT_ID \
  -H "Authorization: Bearer $SHOPPING_API_KEY"

MCP-Server

Ein Model Context Protocol-Server stellt die Einkaufsliste MCP-Clients (z. B. ChatGPT) zur Verfügung. Er kommuniziert nur mit der oben genannten REST-API – niemals direkt mit productRepository.ts oder data/products.json –, sodass er unabhängig von dem verwendeten Persistenz-Backend der API bleibt.

MCP client → MCP server → REST API → productRepository → data/products.json

Endpunkt: /api/mcp (Streamable HTTP Transport), implementiert in src/app/api/[transport]/route.ts über mcp-handler.

Tools:

Tool

Beschreibung

list_products

Produkte auflisten, optional gefiltert nach Person

add_product

Ein Produkt für eine Person hinzufügen

update_product

Name/Person/Gekauft-Status eines Produkts ändern

mark_product_purchased

Bequemes Tool, um ein Produkt als (nicht) gekauft zu markieren

delete_product

Ein Produkt löschen

Erfordert dasselbe Bearer-Token wie die REST-API (siehe Authentifizierung). Testen Sie ihn lokal mit dem MCP Inspector:

npx @modelcontextprotocol/inspector --cli http://localhost:3000/api/mcp --method tools/list \
  --header "Authorization: Bearer $SHOPPING_API_KEY"

Umgebungsvariablen

Variable

Erforderlich

Beschreibung

SHOPPING_API_BASE_URL

Nein

Basis-URL, die der MCP-Server zum Aufrufen der REST-API verwendet. Standardmäßig http://localhost:3000 lokal bzw. https://$VERCEL_URL auf Vercel. Explizit setzen, wenn Sie in der Produktion eine benutzerdefinierte Domain verwenden.

SHOPPING_API_KEY

Ja

Gemeinsames Geheimnis, das als Authorization: Bearer <key> von der REST-API und dem MCP-Endpunkt benötigt wird. Anfragen ohne passendes Token werden abgelehnt.

Siehe .env.example.

Authentifizierung

Die REST-API und der MCP-Endpunkt erfordern beide ein Bearer-Token – ein einzelnes gemeinsames Geheimnis, das über SHOPPING_API_KEY konfiguriert wird. Es gibt keinen benutzerbezogenen Login; dies ist eine einfache statische Token-Prüfung, die für einen Prototyp geeignet ist, nicht für eine vollständige OAuth-Implementierung.

curl http://localhost:3000/api/products \
  -H "Authorization: Bearer $SHOPPING_API_KEY"

Eine Anfrage mit fehlendem oder falschem Token erhält 401 Unauthorized. Wenn SHOPPING_API_KEY auf dem Server überhaupt nicht gesetzt ist, werden Anfragen mit 500 abgelehnt (Fail-Closed, nicht Open).

Server Actions (src/app/actions.ts) sind davon nicht betroffen – sie rufen productRepository direkt auf dem Server auf und durchlaufen niemals die REST-API, daher benötigen sie kein Token.

Bekannte Einschränkungen

  • Keine Authentifizierung/Autorisierung weder auf der REST-API noch auf dem MCP-Server – jeder kann alle Produkte sehen und bearbeiten. Als Folgearbeit geplant.

  • Gleichzeitige Schreibvorgänge werden innerhalb eines einzelnen Prozesses serialisiert (eine einfache Warteschlange in productRepository.ts), was für einen Prototyp in Ordnung ist, aber nicht für Produktionsumgebungen mit mehreren Instanzen.

  • Wie oben erwähnt, ist die Persistenz auf serverlosen Plattformen wie Vercel nicht deployment-sicher – eine echte Datenbank (z. B. Turso) ist der nächste geplante Schritt.

Deployment

Die App kann wie jedes Next.js-Projekt bereitgestellt werden, z. B. auf Vercel. Vor dem Einsatz in der Produktion sollte die Datenpersistenzschicht (siehe oben) gegen eine echte Datenbank ausgetauscht werden.

Mehr zu Next.js: Next.js-Dokumentation · Next.js lernen

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Shopping MCP for AI agents: search, compare, Amazon buy links. Auto-register.

  • Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.

  • Connect e-commerce and marketing data to AI assistants via MCP.

View all MCP Connectors

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/bbwrl/shopping-list-mcp-server'

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