Skip to main content
Glama
SIRGPrice

miel-ruben MCP Server

by SIRGPrice
README.md
# Miel Rubén — Tienda online

**Demo online:** https://sirgprice.github.io/miel-ruben-web/

**Demo local (Windows):** https://github.com/SIRGPrice/miel-ruben-web/releases/latest/download/demo-local.bat

Web completa para la venta de miel, derivados de la apicultura y abejas reinas
seleccionadas genéticamente. Una sola app autocontenida: **Node.js + Express +
SQLite**, sin servicios externos de base de datos.

- Frontend estático bilingüe (ES/EN), sin frameworks, con gráficos SVG propios
  (composición de la miel, espectro polínico, razas de abejas, floraciones).
- Pagos **solo con tarjeta** mediante Stripe Payment Element (3D Secure incluido).
- Al completarse el pago: **email de confirmación + factura PDF al cliente** y
  **copia al email del propietario** (SMTP propio).
- Gestión de pedidos por 3 vías con la misma lógica: **panel web admin**,
  **API REST** y **servidor MCP** (controlable por cualquier modelo de IA:
  Claude, GPT, Gemini, modelos locales…).
- **Sin logging de ningún tipo**: sin analytics, sin registros de acceso, sin
  cookies de terceros. Solo datos de negocio (pedidos/facturas) en SQLite.

## 1. Requisitos

- Node.js ≥ 20
- Cuenta de Stripe (pagos con tarjeta)
- Cuenta de correo SMTP (envío de confirmaciones y facturas)

## 2. Puesta en marcha local

### 2.1 Modo demo local (sin Stripe ni SMTP)

Para ver y probar la web al completo **sin configurar ningún servicio
externo** (los servicios no conectados se muestran en la UI, pero el cobro
se simula en el servidor):

#### Windows — descarga y ejecuta el lanzador

`demo-local.bat`: https://github.com/SIRGPrice/miel-ruben-web/releases/latest/download/demo-local.bat
1. Comprueba Node.js y Git (abre sus páginas si faltan).
2. Descarga el proyecto (o lo actualiza) en `%USERPROFILE%\miel-ruben-web`.
3. Instala dependencias la primera vez.
4. Sirve la web en **modo demo** y abre el navegador en `http://localhost:3000`.

> La primera vez `git clone` pedirá tu sesión de GitHub (repo privado).
> Windows SmartScreen puede avisar al ejecutar un `.bat` descargado:
> **"Más información → Ejecutar de todos modos"**.

#### macOS / Linux
Descarga **`demo-local.sh`** y ejecútalo:
```bash
curl -L -o demo-local.sh https://github.com/SIRGPrice/miel-ruben-web/releases/latest/download/demo-local.sh
chmod +x demo-local.sh
./demo-local.sh
```
(Equivale al `.bat` pero en shell: Node.js + Git requeridos; abre el navegador
con `open` / `xdg-open` cuando el servidor esté listo.)

Si ya tienes el repo clonado, basta con:
```bash
npm install
npm run demo          # http://localhost:3000
```
En Windows también puedes hacer **doble click en `start-local.bat`**
(instala dependencias si faltan, abre el navegador y arranca).

En modo demo:
- El checkout muestra una **tarjeta ficticia (solo UI)**; al pagar, el pedido
  se registra como pagado con su factura (sin cargo real) y aparece en el
  panel admin y vía MCP.
- Los emails no se envían (SMTP no configurado); todo lo demás funciona.
- Panel admin: `http://localhost:3000/admin.html` → token `demo-admin-token`
  · MCP: `http://localhost:3000/mcp` → token `demo-mcp-token`.
- El endpoint de simulación `/api/demo/*` **solo existe en este modo**;
  en producción ni se registra. **Nunca desplegar con `DEMO_MODE=true`.**

### 2.2 Modo producción (con servicios reales)

```bash
npm install
cp .env.example .env     # rellenar las variables
npm start                # http://localhost:3000
npm test                 # 21 tests de lógica y API
```

## 3. Configuración

### 3.1 Datos del negocio

Todo lo editable está en **`config/business.json`**: nombre, email del
propietario (`ownerEmail`, recibe copia de cada pedido), dirección, CIF,
tipo de IVA, gastos de envío y umbral de envío gratis.

El catálogo está en **`public/data/products.json`** (productos, precios con
IVA incluido, stock inicial, composiciones y espectros polínicos). Las fotos
son placeholders SVG en `public/assets/products/`: sustituir manteniendo el
nombre de archivo o actualizar el campo `image`.

### 3.2 Variables de entorno (`.env`)

| Variable | Descripción |
|---|---|
| `PORT` / `DOMAIN` | Puerto y dominio público (`https://tudominio.com`) |
| `STRIPE_PUBLISHABLE_KEY` / `STRIPE_SECRET_KEY` | Claves API de Stripe |
| `STRIPE_WEBHOOK_SECRET` | Secreto del webhook (ver 4.2) |
| `SMTP_HOST` `SMTP_PORT` `SMTP_SECURE` `SMTP_USER` `SMTP_PASS` `SMTP_FROM` | Servidor de correo saliente |
| `ADMIN_TOKEN` | Token del panel admin y API REST (largo y aleatorio) |
| `MCP_TOKEN` | Token del servidor MCP para IA (largo y aleatorio) |
| `OWNER_EMAIL` | Sobrescribe el email del propietario de `business.json` |
| `DEMO_MODE` | `true` solo para la demo local (pagos simulados). Nunca en producción |

## 4. Despliegue (listo para ligar a un dominio)

### 4.1 Render (recomendado, 1 click)

1. Subir este repo (privado) a GitHub.
2. En Render: **New → Blueprint** → elegir el repo. `render.yaml` crea el
   servicio con disco persistente para SQLite y genera `ADMIN_TOKEN` y
   `MCP_TOKEN` aleatorios.
3. Rellenar las variables `sync: false` (Stripe, SMTP, DOMAIN).
4. En **Custom Domain**: añadir el dominio y crear el registro CNAME que
   indica Render. HTTPS automático.

También funciona en Railway, Fly.io o cualquier VPS (`npm install && npm start`
detrás de un proxy HTTPS).

### 4.2 Webhook de Stripe

En el panel de Stripe → **Developers → Webhooks → Add endpoint**:

- URL: `https://tudominio.com/api/webhooks/stripe`
- Eventos: `payment_intent.succeeded` y `payment_intent.payment_failed`
- Copiar el **Signing secret** en `STRIPE_WEBHOOK_SECRET`.

### 4.3 DNS y SEO

- Sustituir `tudominio.com` en `public/robots.txt` y `public/sitemap.xml`.
- Stripe: activar el dominio en **Settings → Payment method domains**.

## 5. Flujo de compra

1. El cliente arma la cesta y rellena sus datos de envío.
2. El servidor **recalcula los importes desde el catálogo** (nunca se confía
   en el cliente) y crea un `PaymentIntent` con `payment_method_types: ['card']`.
3. Stripe Payment Element cobra con tarjeta (3DS si aplica).
4. El webhook marca el pedido como pagado, genera la **factura PDF**
   (numeración secuencial `MR-AÑO-XXXX`) y envía el **email de confirmación
   con la factura al cliente y copia al propietario**.
5. El cliente ve la página de confirmación con el resumen.

## 6. Gestión de pedidos (propietario)

### 6.1 Panel web

`https://tudominio.com/admin.html` → introducir `ADMIN_TOKEN`.
Pedidos (cambiar estado, cancelar, reenviar factura), KPIs y stock.

Estados: `paid → preparing → shipped → delivered` · `cancelled`.

### 6.2 API REST (mismo token)

```
GET    /api/admin/orders[?status=paid&from=...&to=...]
GET    /api/admin/orders/:id
PATCH  /api/admin/orders/:id            { "status": "shipped" }
POST   /api/admin/orders/:id/cancel
POST   /api/admin/orders/:id/resend-invoice
GET    /api/admin/stats
GET    /api/admin/products
PATCH  /api/admin/products/:id          { "stock": 25, "active": true }
```

Autenticación: `Authorization: Bearer <ADMIN_TOKEN>`.

### 6.3 Servidor MCP (control por cualquier IA)

Endpoint: `POST /mcp` · `Authorization: Bearer <MCP_TOKEN>`
Protocolo: MCP streamable HTTP (JSON-RPC 2.0, respuestas `application/json`).

Herramientas expuestas:

| Tool | Función |
|---|---|
| `list_orders` | Lista pedidos (filtros: estado, fechas, paginación) |
| `get_order` | Detalle completo de un pedido |
| `update_order_status` | Avanza el estado (preparing/shipped/delivered/cancelled) |
| `cancel_order` | Cancela un pedido |
| `resend_invoice` | Regenera y reenvía la factura PDF al cliente |
| `get_sales_stats` | Ingresos, pedidos por estado, ventas por mes, top productos |
| `list_products` | Catálogo con stock |
| `update_stock` | Actualiza stock y/o activación |

Ejemplo de configuración en un harness compatible con MCP (Claude Code,
OpenAI, LM Studio, etc.):

```json
{
  "mcpServers": {
    "miel-ruben": {
      "url": "https://tudominio.com/mcp",
      "headers": { "Authorization": "Bearer <MCP_TOKEN>" }
    }
  }
}
```

Prueba rápida:

```bash
curl -X POST https://tudominio.com/mcp \
  -H "Authorization: Bearer <MCP_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

## 7. Estructura

```
├── config/business.json      # Datos del negocio (EDITAR)
├── public/
│   ├── data/products.json    # Catálogo (EDITAR)
│   ├── assets/products/      # Imágenes (placeholders SVG → sustituir)
│   ├── js/                   # i18n, carrito, charts SVG, tienda, checkout, admin
│   └── *.html                # Inicio, Tienda, Historia, Contacto, Checkout…
├── server/
│   ├── index.js              # App Express (sin logging)
│   ├── routes/               # tienda, webhook Stripe, admin, contacto
│   ├── services/             # pedidos, Stripe, SMTP, factura PDF
│   └── mcp/server.js         # Servidor MCP (control por IA)
├── test/                     # 20 tests (node --test)
└── render.yaml               # Despliegue 1 click
```

## 8. Notas

- **Sin logging**: la app no escribe registros ni incluye analítica. Stripe y
  el proveedor SMTP aplican su propia retención (fuera del código de la app).
- Los precios del catálogo incluyen IVA (tipo en `business.json`, 10 % por
  defecto); la factura desglosa la parte correspondiente.
- Reinas: la venta es estacional (abril–septiembre); gestionar disponibilidad
  con el campo `active`/stock desde el panel o vía MCP.