Skip to main content
Glama
adventureandre

@expertcustom/funilaria-mcp

@expertcustom/funilaria-mcp

Servidor MCP (Model Context Protocol) con las herramientas tipadas que la IA de Aurora usa para escribir y leer en el portal Funilaria & Pintura.

Sustituye a mcp-fetch montando a mano una solicitud HTTP con el secreto escrito en el system prompt: aquí cada operación es una herramienta con schema, descripción y error en portugués.

IA do Aurora ──stdio──> npx @expertcustom/funilaria-mcp ──HTTPS──> backend NestJS

Según la ADR-001, este paquete es un adaptador: ninguna regla de negocio vive aquí. Cada herramienta llama a un endpoint que ya existe, y el servicio del backend sigue siendo el dueño de la decisión.

Herramientas

Herramienta

Endpoint

Autenticación

Qué hace

publicar_noticia

POST /noticias/ingestao

servicio

Entrega una noticia al CMS como borrador. Publicar sigue siendo un acto humano.

responder_busca_peca

POST /buscas/webhook/resposta-fornecedor

servicio

Registra la respuesta cruda del proveedor en WhatsApp; el backend extrae precio, plazo y condición.

lanzar_consumo

POST /estoque/webhook/whatsapp

servicio

Lanza el consumo de material a partir del mensaje del empleado. Envía en respostaParaOFuncionario el texto a mandar de vuelta.

consultar_estoque

GET /estoque

servicio + shopId

Saldo de los materiales del taller, con énfasis en lo que está por debajo del mínimo.

consultar_balancete

GET /estoque/balancete

servicio + shopId

Consumo, entrada, pérdida y costo del período, por material y por empleado.

buscar_fornecedor

GET /fornecedores

pública

Directorio de proveedores con filtros de nombre, tipo, categoría y localidad.

Autenticación

Credencial de servicio con shopId explícito es el camino principal, tanto para escribir como para leer. Header x-aurora-secret, el mismo valor de AURORA_WEBHOOK_SECRET en el backend; no representa a ninguna persona, representa al servicio.

Una IA que atiende a varios talleres no tiene sesión, por lo que la oficina es un parámetro, nunca un contexto implícito. Del lado del backend esto es el @AllowService() en las rutas de lectura de existencias: el JwtAuthGuard acepta el secreto en lugar del JWT y el ShopContextGuard pasa a exigir el shopId: un id inexistente responde 404 Oficina no encontrada, y no una lista vacía que se confundiría con "oficina sin stock".

Sesión de usuario (JWT de POST /auth/entrar) sigue soportada para desarrollo local: sin shopId, la oficina viene de la sesión. El access token dura ~15 min, así que el cliente lo renueva solo mediante el refresh token y regraba el par rotado. Pasar shopId en este modo se rechaza en el acto, con explicación: la ruta devolvería la oficina de la sesión como si fuera la pedida.

Configuración: la env es el camino principal

En producción quien inicia este proceso es el runtime de Aurora, que inyecta las variables: no hay terminal, y no se ejecuta ningún comando de login. El servidor funciona con el disco totalmente vacío.

Env

Apodo aceptado

Para qué

FUNILARIA_API_URL

PUBLIC_API_URL

URL de la API

FUNILARIA_SERVICE_SECRET

AURORA_WEBHOOK_SECRET

Secreto de servicio (x-aurora-secret)

FUNILARIA_SIGNING_SECRET

AURORA_WEBHOOK_SIGNING_SECRET

Secreto de firma HMAC (opcional)

FUNILARIA_SHOP_ID

Oficina por defecto de consultar_estoque

FUNILARIA_TOKEN

JWT de usuario, si existe (opcional)

Los apodos existen para el error clásico de copiar el .env del backend y que el secreto "desaparezca" por el prefijo distinto. AURORA_WEBHOOK_SECRET es exactamente el mismo valor en ambos lados.

El secreto nunca está hardcodeado ni se lee de un prompt. El archivo ~/.config/funilaria-mcp/credentials.json (modo 0600) es una comodidad de desarrollo local; la env siempre gana y nunca se escribe en disco.

En el arranque, el servidor escribe en stderr (stdout es del protocolo MCP) una línea en la que se indica qué está configurado y de dónde viene cada cosa — nunca el valor. Es lo que aparece en el log de Aurora cuando alguien no escribe bien el nombre de la variable:

[funilaria-mcp] API: https://api.exemplo.com (FUNILARIA_API_URL) · Credencial de serviço: configurada via AURORA_WEBHOOK_SECRET · ...
[funilaria-mcp] Sem credencial de serviço: as tools de escrita vão recusar toda chamada. Defina FUNILARIA_SERVICE_SECRET no ambiente deste processo.

Firma HMAC

Cuando existe FUNILARIA_SIGNING_SECRET, toda operación de escritura lleva también:

x-timestamp: <epoch em segundos>
x-signature: sha256=<HMAC-SHA256(`${timestamp}.${corpo}`)>

Es la mejora mapeada en la ADR-001 (fecha replay y fugas por log). El backend aún no lo verifica — un header desconocido se ignora, así que se puede activar el lado del servidor sin romper los que ya están en ejecución.

Instalación

En la IA de Aurora (producción)

Registra el servidor con las variables en el propio registro del MCP — nada de login, nada de secreto en el system prompt:

{
  "command": "npx",
  "args": ["-y", "@expertcustom/funilaria-mcp"],
  "env": {
    "FUNILARIA_API_URL": "https://<api-do-portal>",
    "FUNILARIA_SERVICE_SECRET": "<mesmo valor de AURORA_WEBHOOK_SECRET>"
  }
}

Local, para desarrollar

# opção A — env no shell (igual à produção)
FUNILARIA_API_URL=http://localhost:3334 FUNILARIA_SERVICE_SECRET=... npx @expertcustom/funilaria-mcp

# opção B — guardar em ~/.config para não exportar em todo shell
npx @expertcustom/funilaria-mcp login-servico

# sessão de usuário: só é necessária para consultar_estoque sem shopId
npx @expertcustom/funilaria-mcp login

# conferir o que está valendo e de onde veio (nunca imprime segredo)
npx @expertcustom/funilaria-mcp status

# registrar no Claude Code
claude mcp add funilaria --env FUNILARIA_API_URL=http://localhost:3334 -- npx -y @expertcustom/funilaria-mcp

Pendientes en el backend

Las cuatro pendientes originales (webhook de stock inalcanzable, lectura sin credencial de servicio, secreto comprobado después de la validación, distancia como código muerto) fueron corregidas en el backend y revalidadas contra localhost:3334. Lo que queda:

  1. La IA no tiene cómo descubrir el shopId. Es el único dato que necesita saber de memoria, y hoy solo llega por FUNILARIA_SHOP_ID — lo que ata un servidor a una sola oficina y tumba el caso multi-oficina que motivó el diseño del servicio.

    El punto más barato de resolver es lanzar_consumo: el backend ya ha identificado al empleado y a la oficina por el número de WhatsApp, pero devuelve solo el texto de confirmación. Si IntakeResult incluyera shopId y memberId, la conversación podría ser fluida — "usé 100 ml de barniz" → "cuánto gasté este mes?" sería consultar_balancete con los dos ids en mano. Sin esto, la segunda pregunta no tiene respuesta posible.

  2. GET /estoque/movimentos quedó fuera del @AllowService(). El shopId está declarado en el ListMovementsDto, pero la ruta no acepta la credencial de servicio — el parámetro no tiene forma de usarse. O se marca la ruta, o se quita el campo del DTO para no sugerir una capacidad que no existe.

  3. Firma HMAC aún no verificada. El cliente ya envía x-timestamp y x-signature cuando hay secreto de firma (ver arriba). Falta el lado del servidor para cerrar el replay y las fugas por log, como prevé la ADR-001.

Desarrollo

npm install
npm run build     # tsc estrito, gera dist/
npm start         # sobe o servidor MCP em stdio
-
license - not tested
Not graded
quality - not tested
B
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 Connectors

  • 100+ MCP tools for AI agents: content metadata, trade intelligence, business-expertise analysis.

  • OCR, transcription, file extraction, and image generation for AI agents via MCP.

  • Free public MCP for AI agents — 193 tools, 44 workflows. No API key.

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/adventureandre/funilaria-mcp'

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