Skip to main content
Glama
bbwrl

Shopping List MCP Server

by bbwrl

쇼핑 목록 앱

Next.js 15(App Router)로 구축된 간단한 쇼핑 목록 앱입니다. 모든 제품은 특정 사람에게 속하며, 구매 완료 표시 및 삭제가 가능합니다.

이 프로젝트는 의도적으로 작게 제작되었습니다 — IMS Praxis 5를 위한 학습/연습 프로젝트입니다.

기능

  • 제품 추가, 구매 완료 표시, 삭제

  • 사람별 필터링

  • 간단한 JSON 파일을 통한 데이터 유지 (데이터베이스 서버 불필요)

  • 데이터 작업을 위한 세 가지 방식:

    • 서버 액션 – 프론트엔드에서 직접 사용 (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 서버

Model Context Protocol 서버가 쇼핑 목록을 MCP 클라이언트(예: ChatGPT)에 제공합니다. 이 서버는 오직 위의 REST API와만 통신합니다 — productRepository.ts나 data/products.json에 직접 접근하지 않으므로 API가 사용하는 데이터 유지 백엔드와 독립적입니다.

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

엔드포인트: /api/mcp(Streamable HTTP 전송), src/app/api/[transport]/route.ts에서 mcp-handler를 통해 구현됨.

도구:

도구

설명

list_products

제품 목록 조회, 선택적으로 사람별 필터링

add_product

특정 사람을 위한 제품 추가

update_product

제품의 이름/사람/구매 상태 업데이트

mark_product_purchased

제품의 구매 상태를 (미)구매로 표시하는 편의 도구

delete_product

제품 삭제

REST API와 동일한 Bearer 토큰이 필요합니다(인증 참조). 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 토큰이 필요합니다 — 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