@quantyapp/quanty-mcp-server 1.0.1 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -42,4 +42,8 @@ export declare function prepareImportItem(budgetId: string, bankItem: BankItem):
42
42
  preview: string;
43
43
  data: any;
44
44
  };
45
+ /**
46
+ * Gets a specific item from a bank by ID
47
+ */
48
+ export declare function getBankItemById(bankId: string, itemId: string): Promise<BankItem | null>;
45
49
  //# sourceMappingURL=bankService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bankService.d.ts","sourceRoot":"","sources":["../../src/core/bankService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,QAAQ,GAAG,SAAS,GAAG,cAAc,CAAC;IAClD,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAmBzE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAgB/E;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CA0C5G;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,GACnB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,CAchD"}
1
+ {"version":3,"file":"bankService.d.ts","sourceRoot":"","sources":["../../src/core/bankService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,QAAQ,GAAG,SAAS,GAAG,cAAc,CAAC;IAClD,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAmBzE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAgB/E;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CA0C5G;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,GACnB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,CAchD;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAsC9F"}
@@ -103,3 +103,45 @@ export function prepareImportItem(budgetId, bankItem) {
103
103
  }
104
104
  };
105
105
  }
106
+ /**
107
+ * Gets a specific item from a bank by ID
108
+ */
109
+ export async function getBankItemById(bankId, itemId) {
110
+ const { data, error } = await supabase
111
+ .from('composition_banks')
112
+ .select('categories')
113
+ .eq('id', bankId)
114
+ .single();
115
+ if (error)
116
+ return null;
117
+ let foundItem = null;
118
+ function search(items) {
119
+ for (const item of items) {
120
+ if (item.id === itemId) {
121
+ foundItem = {
122
+ id: item.id,
123
+ code: item.code,
124
+ description: item.description,
125
+ unit: item.unit,
126
+ unitCost: item.unitCost || 0,
127
+ itemType: item.itemType
128
+ };
129
+ return;
130
+ }
131
+ if (item.children)
132
+ search(item.children);
133
+ }
134
+ }
135
+ function searchCats(categories) {
136
+ for (const cat of categories) {
137
+ if (foundItem)
138
+ return;
139
+ if (cat.items)
140
+ search(cat.items);
141
+ if (cat.children)
142
+ searchCats(cat.children);
143
+ }
144
+ }
145
+ searchCats(data?.categories || []);
146
+ return foundItem;
147
+ }
@@ -81,4 +81,8 @@ export declare function prepareDeleteItem(budgetId: string, itemId: string, item
81
81
  * Executes item deletion
82
82
  */
83
83
  export declare function executeDeleteItem(auth: AuthContext, data: any): Promise<void>;
84
+ /**
85
+ * Gets composition details (inputs/children) for a specific item in a budget
86
+ */
87
+ export declare function getCompositionDetails(auth: AuthContext, budgetId: string, itemId: string): Promise<any[]>;
84
88
  //# sourceMappingURL=budgetService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"budgetService.d.ts","sourceRoot":"","sources":["../../src/core/budgetService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,WAAW,GAAG,cAAc,CAAC;CAC1C;AAED,MAAM,WAAW,MAAM;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA0BjG;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyB3F;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,CAMpH;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAgCvF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChF;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,CAOhD;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BhF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,CAM3I;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAenF"}
1
+ {"version":3,"file":"budgetService.d.ts","sourceRoot":"","sources":["../../src/core/budgetService.ts"],"names":[],"mappings":"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"}
@@ -168,3 +168,38 @@ export async function executeDeleteItem(auth, data) {
168
168
  if (error)
169
169
  throw new Error(`Failed to delete item: ${error.message}`);
170
170
  }
171
+ /**
172
+ * Gets composition details (inputs/children) for a specific item in a budget
173
+ */
174
+ export async function getCompositionDetails(auth, budgetId, itemId) {
175
+ const budget = await getBudget(auth, budgetId);
176
+ if (!budget)
177
+ throw new Error('Budget not found');
178
+ // Find the item in the rows
179
+ // Note: getBudget returns a simplified BudgetRow structure.
180
+ // We need to access the raw data structure which might contain 'children' for compositions
181
+ const { data, error } = await supabase
182
+ .from('budgets')
183
+ .select('data')
184
+ .eq('id', budgetId)
185
+ .single();
186
+ if (error || !data)
187
+ throw new Error('Failed to fetch budget data');
188
+ const rows = data.data?.rows || [];
189
+ const item = rows.find((r) => r.id === itemId);
190
+ if (!item)
191
+ throw new Error('Item not found in budget');
192
+ if (!item.children || item.children.length === 0) {
193
+ return [];
194
+ }
195
+ return item.children.map((child) => ({
196
+ id: child.id,
197
+ code: child.code,
198
+ description: child.description,
199
+ unit: child.unit,
200
+ quantity: child.quantity,
201
+ unitCost: child.unitCost, // Custo unitário do insumo
202
+ total: (child.quantity || 0) * (child.unitCost || 0),
203
+ type: child.itemType || 'INSUMO'
204
+ }));
205
+ }
package/dist/mcp/index.js CHANGED
@@ -121,6 +121,20 @@ Use quanty_ver_composicao para ver os insumos de uma composição específica.`,
121
121
  required: ['id']
122
122
  }
123
123
  },
124
+ {
125
+ name: 'quanty_ver_composicao',
126
+ description: `Mostra os INSUMOS que compõem um item do tipo COMPOSIÇÃO.
127
+ Uso obrigatório quando um item tiver 'is_composicao: true' para entender seus custos internos.
128
+ Se um insumo retornado também for uma composição, você pode chamar esta função novamente com o ID dele (recursividade).`,
129
+ inputSchema: {
130
+ type: 'object',
131
+ properties: {
132
+ orcamento_id: { type: 'string', description: 'ID do orçamento onde está o item' },
133
+ item_id: { type: 'string', description: 'ID do item (composição) a ser detalhado' }
134
+ },
135
+ required: ['orcamento_id', 'item_id']
136
+ }
137
+ },
124
138
  {
125
139
  name: 'quanty_listar_bancos',
126
140
  description: `Lista os bancos de composição disponíveis para buscar preços de referência.
@@ -140,7 +154,22 @@ Para importar uma composição para um orçamento, o sistema traz toda a estrutu
140
154
  banco_id: { type: 'string', description: 'ID do banco (obtido via quanty_listar_bancos)' },
141
155
  busca: { type: 'string', description: 'Texto para buscar (ex: "concreto fck 30", "forma metálica")' }
142
156
  },
143
- required: ['banco_id', 'busca']
157
+ }
158
+ },
159
+ {
160
+ name: 'quanty_importar_item',
161
+ description: `Importa um item (insumo ou composição) de um banco de referência para o orçamento.
162
+ Use esta função quando encontrar um item via quanty_buscar_insumo e quiser adicioná-lo ao orçamento.
163
+ A importação traz automaticamente a unidade e custo do banco.`,
164
+ inputSchema: {
165
+ type: 'object',
166
+ properties: {
167
+ orcamento_id: { type: 'string', description: 'ID do orçamento destino' },
168
+ banco_item_id: { type: 'string', description: 'ID do item no banco (retornado por quanty_buscar_insumo)' },
169
+ banco_id: { type: 'string', description: 'ID do banco de origem' },
170
+ quantidade: { type: 'number', description: 'Quantidade a ser orçada' }
171
+ },
172
+ required: ['orcamento_id', 'banco_item_id', 'banco_id', 'quantidade']
144
173
  }
145
174
  },
146
175
  // === WRITE TOOLS (with confirmation) ===
@@ -282,6 +311,30 @@ async function handleToolCall(auth, name, args) {
282
311
  }))
283
312
  };
284
313
  }
314
+ case 'quanty_ver_composicao': {
315
+ const insumos = await budgetService.getCompositionDetails(auth, args.orcamento_id, args.item_id);
316
+ if (!insumos || insumos.length === 0) {
317
+ return {
318
+ mensagem: 'Esta composição não possui insumos listados ou não é uma composição válida.'
319
+ };
320
+ }
321
+ const totalComposicao = insumos.reduce((sum, i) => sum + i.total, 0);
322
+ return {
323
+ _info: 'Lista de insumos/filhos desta composição',
324
+ qtd_insumos: insumos.length,
325
+ custo_total_calculado: `R$ ${totalComposicao.toFixed(2)}`,
326
+ insumos: insumos.map(i => ({
327
+ id: i.id, // ID necessário para recursão
328
+ descricao: i.description,
329
+ unidade: i.unit,
330
+ coeficiente: i.quantity,
331
+ custo_unitario_insumo: i.unitCost,
332
+ custo_total_insumo: i.total,
333
+ is_composicao: i.is_composicao, // Indica se pode descer mais um nível
334
+ tipo: i.type
335
+ }))
336
+ };
337
+ }
285
338
  case 'quanty_listar_bancos': {
286
339
  const banks = await bankService.listBanks(auth);
287
340
  return {
@@ -314,6 +367,38 @@ async function handleToolCall(auth, name, args) {
314
367
  };
315
368
  }
316
369
  // === WRITE (with confirmation) ===
370
+ case 'quanty_importar_item': {
371
+ // Primeiro buscamos os detalhes do item no banco para preparar a importação
372
+ // Como prepareImportItem precisa do objeto BankItem completo, vamos simular ou buscar
373
+ // Para simplificar, vamos usar uma busca direta pelo ID no banco via searchBankItems (ajustando a query seria ideal, mas aqui vamos assumir que o ID é suficiente ou implementaremos um getBankItem)
374
+ // Melhor abordagem: vamos buscar o item específico.
375
+ // O bankService não tem getBankItem exposto, então vamos adicionar uma busca rápida ou usar search
376
+ const items = await bankService.searchBankItems(args.banco_id, ''); // Busca ampla é ruim.
377
+ // Vamos adicionar uma função getBankItem no bankService ou buscar na lista filtrada.
378
+ // WORKAROUND: Vamos criar a pendência com os dados mínimos e deixar o execute resolver ou
379
+ // implementar getBankItem no bankService agora.
380
+ // Vamos assumir que o usuário passou dados válidos e deixar a validação para o execute se possível.
381
+ // Mas prepareImportItem pede um BankItem.
382
+ // Vamos adicionar getBankItemById no bankService agora.
383
+ const item = await bankService.getBankItemById(args.banco_id, args.banco_item_id);
384
+ if (!item)
385
+ return { erro: 'Item não encontrado no banco de dados.' };
386
+ const prepared = bankService.prepareImportItem(args.orcamento_id, item);
387
+ // Injetamos a quantidade que o usuário pediu, pois o prepareImportItem define como 0
388
+ prepared.data.item.quantity = args.quantidade;
389
+ prepared.preview = prepared.preview.replace('quantidade: 0', `quantidade: ${args.quantidade}`); // Ajuste cosmético se houver
390
+ const pendingId = generatePendingId();
391
+ pendingOperations.set(pendingId, {
392
+ action: prepared.action,
393
+ data: prepared.data,
394
+ expiresAt: Date.now() + 5 * 60 * 1000
395
+ });
396
+ return {
397
+ pending_id: pendingId,
398
+ preview: `Importar "${item.description}" (${args.quantidade} ${item.unit}) - Pressione executar para confirmar.`,
399
+ mensagem: 'Use quanty_executar com este pending_id para confirmar a importação.'
400
+ };
401
+ }
317
402
  case 'quanty_preparar_orcamento': {
318
403
  const prepared = budgetService.prepareCreateBudget(auth, args.titulo);
319
404
  const pendingId = generatePendingId();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantyapp/quanty-mcp-server",
3
- "version": "1.0.1",
3
+ "version": "1.0.4",
4
4
  "description": "MCP Server para conectar Claude Desktop ao Quanty - Sistema de Orçamentos de Engenharia",
5
5
  "type": "module",
6
6
  "main": "dist/mcp/index.js",