Skip to main content
Glama
bbwrl

Shopping List MCP Server

by bbwrl

购物清单应用

一个基于 Next.js 15(App Router)构建的简单购物清单应用。每个商品归属于一个人,可以标记为已购买,也可以删除。

该项目特意设计得小巧——它是 IMS Praxis 5 的学习/练习项目。

功能

  • 添加商品、标记为已购买、删除商品

  • 按人员筛选

  • 通过简单的 JSON 文件持久化(无需数据库服务器)

  • 三种操作数据的方式:

    • 服务器操作(Server Actions) – 由前端直接使用(src/app/actions.ts)

    • REST API – 通过 /api/products 提供,例如供外部客户端或 curl 使用

    • MCP 服务器 – 通过调用 REST API,将相同的数据以 MCP 工具的形式暴露(例如供 ChatGPT 使用)

Related MCP server: lista-compras-mcp

技术栈

  • Next.js 15 / React 19,App Router

  • TypeScript

  • 无数据库,无 ORM – 通过 JSON 文件持久化(data/products.json)

  • MCP TypeScript SDK 通过 mcp-handler 使用,采用 Streamable HTTP 传输

快速开始

npm install
npm run dev

在 http://localhost:3000 打开应用。

本地运行应用无需配置或 .env 文件。关于 MCP 服务器使用的一个可选设置,请参见环境变量。

项目结构

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)

数据模型

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

持久化

所有商品存放在 data/products.json 中。所有文件访问封装在 src/lib/productRepository.ts 中——无论是 UI 还是 API 路由都不会直接读写该文件。该仓库暴露:

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

注意: 这种基于文件的持久化仅作为原型/开发解决方案。在 Vercel(以及其他无服务器平台)上,本地文件系统在请求或部署之间并不可靠持久——写入可能会丢失。对于生产环境,应将 productRepository.ts 替换为真正的持久化数据库(例如 Turso)。由于应用的其余部分(UI、服务器操作、API 路由)仅通过导出的仓库函数与数据交互,因此这种替换只涉及这一个文件。

前端 ↔ 后端

前端(page.tsx、ProductForm、ProductList)使用 Next.js 服务器操作(src/app/actions.ts)来创建、更新和删除商品。客户端没有 fetch 调用——服务器操作直接调用仓库,然后通过 revalidatePath("/") 触发服务器渲染数据的刷新。

/api/products 下的 REST API 是独立的,可以单独使用(例如供外部工具、脚本或测试使用)——它读写相同的数据源。

REST API

读取商品

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

添加商品

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

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

id、purchased(false)和 createdAt 会自动设置。

更新商品

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

{ "purchased": true }

无需提供所有字段(name、person、purchased 各自可选且可独立更新)。

删除商品

DELETE /api/products/:id

错误响应

{ "error": "Product not found" }

情况

状态码

无效/空请求

400

未知 ID

404

内部错误

500

curl 示例

# 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 服务器

一个模型上下文协议服务器将购物清单暴露给 MCP 客户端(例如 ChatGPT)。它仅与上述 REST API 通信——从不直接访问 productRepository.ts 或 data/products.json——因此它独立于 API 所使用的任何持久化后端。

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

端点: /api/mcp(Streamable HTTP 传输),通过 mcp-handler 在 src/app/api/[transport]/route.ts 中实现。

工具:

工具

描述

list_products

列出商品,可选按人员筛选

add_product

为某人添加商品

update_product

更新商品的名称/人员/已购买状态

mark_product_purchased

便捷工具,将商品标记为(未)已购买

delete_product

删除商品

需要与 REST API 相同的 bearer token(参见身份验证)。使用 MCP Inspector 在本地测试:

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

环境变量

变量

必需

描述

SHOPPING_API_BASE_URL

否

MCP 服务器用于调用 REST API 的基础 URL。本地默认为 http://localhost:3000,在 Vercel 上默认为 https://$VERCEL_URL。如果在生产环境中使用自定义域名,请显式设置。

SHOPPING_API_KEY

是

REST API 和 MCP 端点所需的共享密钥,作为 Authorization: Bearer <key>。不匹配的令牌请求将被拒绝。

参见 .env.example。

身份验证

REST API 和 MCP 端点都需要一个 bearer token——一个通过 SHOPPING_API_KEY 配置的共享密钥。没有按用户登录;这是一个适用于原型的简单静态令牌检查,并非完整的 OAuth。

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

缺少或错误的令牌请求将返回 401 Unauthorized。如果服务器上根本没有设置 SHOPPING_API_KEY,请求将被拒绝并返回 500(故障关闭,而非开放)。

服务器操作(src/app/actions.ts)不受影响——它们直接在服务器上调用 productRepository,从不经过 REST API,因此不需要令牌。

已知限制

  • REST API 和 MCP 服务器均无身份验证/授权——任何人都可以查看和编辑所有商品。计划作为后续改进。

  • 并发写入在单个进程内串行化(productRepository.ts 中的简单队列),这对原型来说没问题,但不适用于生产环境的多实例部署。

  • 如上所述,在 Vercel 等无服务器平台上,持久化在部署中不安全——真正的数据库(例如 Turso)是下一步计划。

部署

该应用可以像任何 Next.js 项目一样部署,例如在 Vercel 上。在生产环境中使用之前,应将数据持久化层(见上文)替换为真正的数据库。

更多关于 Next.js 的信息:Next.js 文档 · 学习 Next.js

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that gives AI agents full control over grocery lists, todos, and packing lists. Your AI creates lists, adds items, checks them off, and shares with family/friends.
    4
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to manage shopping lists and items (create, edit, delete, mark as purchased) via integration with a backend API.
    8
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI assistants to read current pantry inventory and low-stock shopping needs, export a shopping queue, and perform idempotent inventory adjustments and catalog link management through remote MCP tools.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to manage Bring! shopping lists through MCP, including adding, removing, renaming, and batch-updating items while resolving them against Bring's real catalog so they render with the correct language, icon, and aisle.
    MIT