@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 NestJSSegú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 |
|
| servicio | Entrega una noticia al CMS como borrador. Publicar sigue siendo un acto humano. |
|
| servicio | Registra la respuesta cruda del proveedor en WhatsApp; el backend extrae precio, plazo y condición. |
|
| servicio | Lanza el consumo de material a partir del mensaje del empleado. Envía en |
|
| servicio + | Saldo de los materiales del taller, con énfasis en lo que está por debajo del mínimo. |
|
| servicio + | Consumo, entrada, pérdida y costo del período, por material y por empleado. |
|
| 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é |
|
| URL de la API |
|
| Secreto de servicio ( |
|
| Secreto de firma HMAC (opcional) |
| — | Oficina por defecto de |
| — | 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-mcpPendientes 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:
La IA no tiene cómo descubrir el
shopId. Es el único dato que necesita saber de memoria, y hoy solo llega porFUNILARIA_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. SiIntakeResultincluyerashopIdymemberId, la conversación podría ser fluida — "usé 100 ml de barniz" → "cuánto gasté este mes?" seríaconsultar_balancetecon los dos ids en mano. Sin esto, la segunda pregunta no tiene respuesta posible.GET /estoque/movimentosquedó fuera del@AllowService(). ElshopIdestá declarado en elListMovementsDto, 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.Firma HMAC aún no verificada. El cliente ya envía
x-timestampyx-signaturecuando 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 stdioThis server cannot be installed
Maintenance
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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