Skip to main content
Glama
adventureandre

@expertcustom/funilaria-mcp

@expertcustom/funilaria-mcp

AuroraのAIがFunilaria & Pinturaポータルへの書き込み・読み取りに使用する、型付きツールを備えたMCP(Model Context Protocol)サーバーです。

これはmcp-fetchを置き換え、system promptに書かれたシークレットを使ってHTTPリクエストを手動で組み立てます。ここでは各操作が、スキーマ・説明・エラーをポルトガル語で持つツールになっています。

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

ADR-001により、このパッケージはアダプターです。ビジネスルールはここには存在しません。すべてのツールは既存のエンドポイントを呼び出し、バックエンドサービスが決定権を持ち続けます。

ツール — 定義するのはバックエンド

このパッケージはどのツールが存在するかを知りません。起動時にGET /mcp/catalogoを取得して返ってきたものを公開し、実行はPOST /mcp/executarで行われ、バックエンドが名前をサービスに解決します。

subida  ──> GET  /mcp/catalogo   → lista publicada em tools/list
chamada ──> POST /mcp/executar   → { name, args }

理由は運用上のものです。以前は新しいツールを追加するたびに、このパッケージの編集、ビルド、コミット、公開、AuroraへのMCP再インストールという5つのステップが必要で、バックエンドに既に存在するエンドポイントを公開するだけでも手間がかかりました。現在はbackend/src/mcpのモジュール1つをコミットするだけです。

現在のリストはGET /mcp/catalogoから取得します。ここにコピーは意図的に置いていません。コピーは古くなり、嘘をつき始めるからです。

カタログが応答しない場合、サーバーはfunilaria_catalogo_indisponivelという1つのツールだけを公開し、その説明で何を確認すべきかを示します。これがないと「ツールが消えた」という症状になり、診断が間違った場所から始まることになります。

カタログは起動時に1回だけ取得されます。MCPクライアントは接続直後にtools/listを読み取り、再度問い合わせることはありません。バックエンドで追加されたツールは、次回サーバーをAuroraに再インストールしたときに反映されます。

Related MCP server: Telegram Bot MCP Server

認証

shopIdを明示したサービス資格情報が、書き込み・読み取りの両方で主要な経路です。ヘッダーx-aurora-secretは、バックエンドのAURORA_WEBHOOK_SECRETと同じ値です。これは個人を表すものではなく、サービスを表します。

複数の工場を担当するAIにはセッションがないため、工場はパラメーターであり、暗黙のコンテキストではありません。バックエンド側では、これは在庫読み取りルートの@AllowService()です。JwtAuthGuardはJWTの代わりにシークレットを受け入れ、ShopContextGuardはshopIdを要求するようになります。存在しないIDは404 Oficina não encontradaを返し、「工場に在庫がない」と混同される空のリストは返しません。

ユーザーセッション(POST /auth/entrarのJWT)はCLIコマンド用に引き続き存在しますが、ツールにはもう使用されません。POST /mcp/executarは常にサービス呼び出しであり、工場は常に明示的なパラメーターです。複数の工場を担当するAIにセッションはありませんでした。2つのモードを維持すると、shopIdが省略された場合に異なる意味を持つ経路が生まれるだけでした。

設定 — envが主要な経路

本番環境では、このプロセスを起動するのはAuroraのランタイムであり、変数を注入します。ターミナルはなく、ログインコマンドも実行されません。サーバーはディスクが完全に空の状態で動作します。

Env

受け入れられるエイリアス

用途

FUNILARIA_API_URL

PUBLIC_API_URL

APIのベースURL

FUNILARIA_SERVICE_SECRET

AURORA_WEBHOOK_SECRET

サービスシークレット(x-aurora-secret)

FUNILARIA_SIGNING_SECRET

AURORA_WEBHOOK_SIGNING_SECRET

HMAC署名シークレット(オプション)

FUNILARIA_SHOP_ID

—

consultar_estoqueのデフォルト工場

FUNILARIA_TOKEN

—

ユーザーJWT(存在する場合、オプション)

エイリアスは、バックエンドの.envをコピーしてプレフィックスが異なるためにシークレットが「消える」という古典的なエラーに対応するためのものです。AURORA_WEBHOOK_SECRETは両側でまったく同じ値です。

シークレットはハードコードもプロンプトからの読み取りもされません。~/.config/funilaria-mcp/credentials.json(モード0600)はローカル開発の便宜のためだけのもので、envが常に優先され、ディスクに書き込まれることはありません。

起動時にサーバーはstderr(stdoutはMCPプロトコル用)に、何が設定されているか、各項目がどのenvから来たかを1行で書き出します。値は決して書きません。これは、誰かが変数名を間違えたときにAuroraのログに表示されるものです。

[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署名

FUNILARIA_SIGNING_SECRETが存在する場合、すべての書き込みには次のものも含まれます。

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

これはADR-001で計画された改善です(リプレイとログ漏洩を防ぎます)。バックエンドはまだ検証していません。未知のヘッダーは無視されるため、既に実行中のものを壊すことなくサーバー側を有効にできます。

インストール

AuroraのAI(本番)

MCPの登録自体に変数を指定してサーバーを登録します。ログインも、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>"
  }
}

ローカル開発用

# 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

バックエンドの未解決事項

元の4つの未解決事項(在庫ウェブフックに到達できない、サービス資格情報なしでの読み取り、検証後にシークレットがチェックされる、距離がデッドコード)はバックエンドで修正され、localhost:3334に対して再検証されました。残っているもの:

  1. AIがshopIdを発見する方法がない。 これはAIが暗記する必要がある唯一のデータであり、現在はFUNILARIA_SHOP_ID経由でのみ届きます。これによりサーバーが1つの工場に縛られ、サービス設計の動機となった複数工場のケースが崩れます。

    最も安価な解決ポイントはlancar_consumoです。バックエンドはすでにWhatsApp番号から従業員と工場を特定していますが、確認テキストだけを返します。IntakeResultにshopIdとmemberIdが含まれていれば、会話はスムーズに進みます。「100mlのワニスを使った」→「今月はいくら使った?」は、2つのIDを手にしたconsultar_balanceteになります。これがないと、2番目の質問には答えられません。

  2. GET /estoque/movimentosが@AllowService()の対象外。 shopIdはListMovementsDtoで宣言されていますが、ルートはサービス資格情報を受け入れないため、パラメーターを使用する方法がありません。ルートをマークするか、存在しない機能を示唆しないようにDTOからフィールドを削除する必要があります。

  3. HMAC署名がまだ検証されていない。 クライアントは署名シークレットがある場合、x-timestampとx-signatureをすでに送信しています(上記参照)。ADR-001が想定するように、リプレイとログ漏洩を防ぐにはサーバー側の実装が不足しています。

開発

npm install
npm run build     # tsc estrito, gera dist/
npm start         # sobe o servidor MCP em stdio

Available Tools

1 tool
funilaria_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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines5/5

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. 1 tool updatev0.1.0
    • First observedfunilaria_catalogo_indisponivel

TDQS

A4.1/5.0

Scored across 1 tool

Disambiguation5/5

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.

Naming Consistency5/5

The single tool name is descriptive and domain-specific, following a clear pattern. With no other tools, there is no inconsistency to penalize.

Tool Count1/5

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.

Completeness1/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers