@expertcustom/funilaria-mcp
This server is currently in a fallback state: it only provides a single tool that reports the Funilaria catalog is unavailable.
Can only invoke
funilaria_catalogo_indisponivel, which explains that no portal tools are available.Cannot perform any actual read or write operations on the Funilaria portal (e.g., stock, parts, movements).
The tool guides the user to check
FUNILARIA_API_URLand service secret configuration.It exists to avoid silently missing tools and directs the user to the stderr log for the exact cause.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@expertcustom/funilaria-mcpQual o saldo de estoque da oficina 10?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@expertcustom/funilaria-mcp
MCP (Model Context Protocol) server with the typed tools that Aurora's AI uses to write and read on the Funilaria & Pintura portal.
It replaces mcp-fetch by building the HTTP request by hand with the secret written in the system prompt: here each operation is a tool with schema, description, and error in Portuguese.
IA do Aurora ──stdio──> npx @expertcustom/funilaria-mcp ──HTTPS──> backend NestJSPer ADR-001, this package is an adapter: no business rules live here. Every tool calls an endpoint that already exists, and the backend service remains the owner of the decision.
Tools — the backend defines them
This package does not know which tools exist. On startup it fetches GET /mcp/catalogo and publishes whatever comes back; execution goes through POST /mcp/executar, and the backend resolves the name to the service.
subida ──> GET /mcp/catalogo → lista publicada em tools/list
chamada ──> POST /mcp/executar → { name, args }The reason is operational: before, a new tool cost editing this package, building, committing, publishing, and reinstalling the MCP in Aurora — five steps to expose an endpoint that already existed in the backend. Now it's a single module commit in backend/src/mcp.
The current list comes from GET /mcp/catalogo. There is deliberately no copy of it here: a copy ages and starts lying.
When the catalog does not respond, the server publishes a single tool, funilaria_catalogo_indisponivel, whose description explains what to check. Without it, the symptom would be "the tools disappeared" and the diagnosis would start in the wrong place.
The catalog is fetched once, on startup: the MCP client reads tools/list right after connecting and does not ask again. A tool added in the backend goes live on the next server reinstall in Aurora.
Related MCP server: Telegram Bot MCP Server
Authentication
Service credential with explicit shopId is the main path, both for writing and reading. Header x-aurora-secret, the same value as AURORA_WEBHOOK_SECRET in the backend; it does not represent any person, it represents the service.
An AI that serves multiple shops has no session, so the shop is a parameter, never implicit context. On the backend side this is the @AllowService() on the stock reading routes: the JwtAuthGuard accepts the secret in place of the JWT, and the ShopContextGuard then requires the shopId — a nonexistent id responds with 404 Oficina não encontrada, not an empty list that could be mistaken for "shop with no stock".
User session (JWT from POST /auth/entrar) still exists for CLI commands, but no longer applies to the tools: POST /mcp/executar is always a service call, and the shop is always an explicit parameter. An AI that serves multiple shops never had a session; keeping both modes only created a path where an omitted shopId meant different things.
Configuration — env is the main path
In production, whoever starts this process is the Aurora runtime, which injects the variables: there is no terminal, and no login command is executed. The server works with a completely empty disk.
Env | Accepted alias | Purpose |
|
| API base URL |
|
| Service secret ( |
|
| HMAC signing secret (optional) |
| — | Default shop for |
| — | User JWT, if any (optional) |
The aliases exist for the classic mistake of copying the backend's .env and the secret "disappearing" because of the different prefix — AURORA_WEBHOOK_SECRET is exactly the same value on both sides.
Secrets are never hardcoded or read from the prompt. The file ~/.config/funilaria-mcp/credentials.json (mode 0600) is a local development convenience; the env always wins and is never written to disk.
On boot, the server writes to stderr (stdout is for the MCP protocol) a line saying what is configured and which env each thing came from — never the value. That is what appears in the Aurora log when someone gets the variable name wrong:
[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.HMAC signing
When FUNILARIA_SIGNING_SECRET exists, every write also carries:
x-timestamp: <epoch em segundos>
x-signature: sha256=<HMAC-SHA256(`${timestamp}.${corpo}`)>This is the improvement mapped in ADR-001 (closes replay and log leakage). The backend does not verify it yet — unknown headers are ignored, so you can enable the server side without breaking what is already running.
Installation
In Aurora's AI (production)
Register the server with the variables in the MCP registration itself — no login, no secret in the 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, for development
# 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-mcpBackend pending items
The four original pending items (unreachable stock webhook, reading without service credential, secret checked after validation, distance as dead code) were fixed in the backend and revalidated against localhost:3334. What remains:
The AI has no way to discover the
shopId. It is the only piece of data it needs to know by heart, and today it only arrives viaFUNILARIA_SHOP_ID— which ties one server to one shop and breaks the multi-shop case that motivated the service design.The cheapest point to solve is
lancar_consumo: the backend already identifies the employee and shop by the WhatsApp number, but only returns the confirmation text. IfIntakeResultincludedshopIdandmemberId, the conversation would flow — "I used 100ml of varnish" → "how much did I spend this month?" would beconsultar_balancetewith both ids in hand. Without that, the second question has no possible answer.GET /estoque/movimentoswas left out of@AllowService(). TheshopIdis declared inListMovementsDto, but the route does not accept service credentials — the parameter has no way to be used. Either mark the route, or remove the field from the DTO so it does not suggest capability that does not exist.HMAC signing is still not verified. The client already sends
x-timestampandx-signaturewhen there is a signing secret (see above). The server side is missing to close replay and log leakage, as ADR-001 provides.
Development
npm install
npm run build # tsc estrito, gera dist/
npm start # sobe o servidor MCP em stdioAvailable Tools
1 toolfunilaria_catalogo_indisponivelCatálogo do Funilaria indisponívelA
O backend do Funilaria não respondeu GET /mcp/catalogo, então NENHUMA tool do portal está disponível nesta sessão — não é que elas não existam. Verifique se FUNILARIA_API_URL aponta para o backend certo e se FUNILARIA_SERVICE_SECRET (ou AURORA_WEBHOOK_SECRET) está definido no processo deste MCP; o motivo exato saiu no stderr do servidor. Não tente cumprir a tarefa por outro caminho: não monte requisição HTTP à mão, não invente URL nem segredo. Avise quem pediu que a integração com o portal está fora do ar.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explains that the tool is not a functional operation but a signal that the catalog is down, that no portal tools are available, and that the exact cause is in the server's stderr. It also discloses the expected fallback behavior (informing the requester) and explicitly forbids bypass attempts. This fully discloses the tool's non-functional nature and the reasoning behind it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, dense paragraph that front-loads the core message (backend down, no tools available) and then provides corrective actions and prohibitions. Every sentence contributes essential information: the root cause, the implication, troubleshooting steps, and explicit instructions. There is no fluff or redundancy, making it both concise and structurally sound.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there is no output schema and the tool is essentially a status indicator, the description is complete. It specifies what happened, why, what to check, what not to do, and what to tell the requester. All necessary operational context is provided, and because the tool has zero parameters and no output expectations, the description fully covers what an agent needs to handle this situation correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema is empty with 0 parameters, so the baseline is 4. The description does not need to add parameter details, but it explains why the tool takes no arguments (it is a placeholder for an unavailable catalog). It also provides environment variable checks (FUNILARIA_API_URL, FUNILARIA_SERVICE_SECRET) as context, which indirectly explains the setup. This exceeds the baseline by giving operational context beyond the mere absence of parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool indicates the backend did not respond to GET /mcp/catalogo, making the entire portal's tools unavailable in this session. It does not use a classic verb+resource phrasing, but its purpose as an unavailability signal is unambiguous and distinct from any normal tool. Since there are no siblings, the distinguishing aspect is not relevant, but the description still clearly explains what it represents.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs when to use this tool (when it appears, treat it as a session-wide unavailability) and what NOT to do: do not attempt to fulfill the task by other means, do not craft HTTP requests manually, do not invent URLs or secrets. It also tells the agent to inform the requester. This is direct, actionable context with explicit exclusions, covering both usage and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.1.0- First observed
funilaria_catalogo_indisponivel
TDQS
Scored across 1 tool
With only one tool, there is no possibility of tool confusion. The tool's purpose—to report that the catalog is unavailable—is uniquely clear.
The single tool name is descriptive and domain-specific, following a clear pattern. With no other tools, there is no inconsistency to penalize.
A single tool that serves only as an error placeholder is far below the expected scope for a catalog server. This is an extreme mismatch with the apparent purpose.
The server provides no actual catalog operations; the only tool explicitly states that all functional tools are unavailable. The surface is severely incomplete and unusable.
Maintenance
Related MCP Connectors
100+ MCP tools for AI agents: content metadata, trade intelligence, business-expertise analysis.
Pay-per-use tool marketplace for AI agents. Search, price-check, and call APIs via MCP.
The Mercado Pago MCP Server implements the Model Context Protocol to provide AI agents and LLMs with access to Mercado Pago's APIs and tools within compatible development environments. It acts as an intermediary that translates Mercado Pago resources into executable functions (tools) that AI applications can invoke to perform actions and automate flows. The server simplifies integration, enables using documentation to implement or improve code, and optimizes operations through natural language interactions without manual implementations.
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage and interact with WordPress sites through MCP, providing tools for content creation, moderation, WooCommerce operations, and governance.47GPL 2.0
- AlicenseAqualityDmaintenanceEnables AI assistants to publish, edit, search, and manage messages in Telegram channels via a set of MCP tools.8MIT
- AlicenseBqualityDmaintenanceEnables AI assistants to interact with Labradoc's document management, email ingestion, task extraction, and integration features through MCP tools.175 npmMIT
- AlicenseNot gradedqualityDmaintenanceProvides AI assistants with access to ProductLane support threads, contacts, changelogs, and documentation through a set of MCP tools.MIT