@comando.one/mcp-server 0.3.0 → 0.3.2

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.
package/README.md CHANGED
@@ -51,7 +51,7 @@ Ambos expõem o **mesmo conjunto de ferramentas** (50 curadas + `lookups` + `com
51
51
 
52
52
  ## Como funciona
53
53
 
54
- - **126 tools curadas** (gerados a partir do OpenAPI canônico, zero drift) cobrindo as operações de maior valor — `customers_list`, `invoices_create`/`invoices_delete`, `charges_create`, `nfse_emit`, `payouts_create`, `contracts_pause`/`contracts_resume`, `service_categories_create`, `reports_aging_actions`/`reports_cashflow_forecast`, `audit_timeline`, `cost_centers_create`, etc.
54
+ - **127 tools curadas** (gerados a partir do OpenAPI canônico, zero drift) cobrindo as operações de maior valor — `customers_list`, `invoices_create`/`invoices_delete`, `charges_create`, `nfse_emit`, `payouts_create`, `contracts_pause`/`contracts_resume`, `service_categories_create`, `reports_aging_actions`/`reports_cashflow_forecast`, `audit_timeline`, `documents_analyze` (lê boleto/guia/NF anexada e extrai valor, vencimento e emitente), `cost_centers_create`, etc.
55
55
  - **`comando_request`** — escape hatch genérico (`method`, `path`, `query`, `body`) que cobre 100% dos endpoints restantes.
56
56
  - **`lookups`** — catálogos read-only (centros de custo, condições/métodos de pagamento, naturezas, contas bancárias).
57
57
  - **`whoami`** — identidade, empresas acessíveis e scopes da chave.
package/dist/index.js CHANGED
@@ -192,6 +192,7 @@ var MANIFEST = [
192
192
  { operationId: "reverseSplitExecution", tool: "split_reverse", write: true, destructive: true },
193
193
  { operationId: "releaseSplitItem", tool: "split_release_item", write: true },
194
194
  // Auditoria
195
+ { operationId: "analyzeDocument", tool: "documents_analyze", write: true },
195
196
  { operationId: "getAuditTimeline", tool: "audit_timeline" },
196
197
  // Categorias de serviço
197
198
  { operationId: "listServiceCategories", tool: "service_categories_list" },
@@ -2217,6 +2218,51 @@ var OPENAPI_SPEC = {
2217
2218
  responses: { "200": paginatedResponse("#/components/schemas/ServiceUnit"), ...COMMON_ERRORS }
2218
2219
  }
2219
2220
  },
2221
+ "/documents/analyze": {
2222
+ post: {
2223
+ tags: ["Documentos"],
2224
+ summary: "Analisar documento anexado",
2225
+ operationId: "analyzeDocument",
2226
+ description: "L\xEA um anexo da empresa (PDF, imagem ou texto) e extrai os campos financeiros: tipo do documento, valor, vencimento, n\xFAmero, emitente, linha digit\xE1vel do boleto e chave Pix. Usa o texto do arquivo e, quando ele n\xE3o basta (PDF escaneado), a leitura visual do modelo.",
2227
+ security: [{ ApiKeyAuth: ["documents:read"] }],
2228
+ requestBody: {
2229
+ required: true,
2230
+ content: { "application/json": { schema: {
2231
+ type: "object",
2232
+ properties: {
2233
+ attachment_id: { type: "string", format: "uuid", description: "UUID do anexo em entity_attachments." },
2234
+ file_name: { type: "string", description: "Alternativa ao id: parte do nome do arquivo." }
2235
+ }
2236
+ } } }
2237
+ },
2238
+ responses: {
2239
+ "200": {
2240
+ description: "Campos extra\xEDdos do documento",
2241
+ content: { "application/json": { schema: {
2242
+ type: "object",
2243
+ properties: {
2244
+ attachment_id: { type: "string", format: "uuid" },
2245
+ file_name: { type: "string" },
2246
+ kind: { type: "string", description: "boleto | arrecadacao | nfe | nfse | fatura | recibo | desconhecido" },
2247
+ direction: { type: "string", description: "pagar | receber | indefinido" },
2248
+ amount: { type: "number", nullable: true },
2249
+ due_date: { type: "string", format: "date", nullable: true },
2250
+ document_number: { type: "string", nullable: true },
2251
+ barcode: { type: "string", nullable: true },
2252
+ digitable_line: { type: "string", nullable: true },
2253
+ pix_key: { type: "string", nullable: true },
2254
+ counterparty_name: { type: "string", nullable: true },
2255
+ counterparty_document: { type: "string", nullable: true },
2256
+ is_own_company_document: { type: "boolean", description: "O documento encontrado \xE9 o da pr\xF3pria empresa (contribuinte/pagador)." },
2257
+ missing: { type: "array", items: { type: "string" }, description: "Campos essenciais que n\xE3o foi poss\xEDvel extrair." },
2258
+ extracted: { type: "boolean" }
2259
+ }
2260
+ } } }
2261
+ },
2262
+ "404": { description: "Documento n\xE3o encontrado" }
2263
+ }
2264
+ }
2265
+ },
2220
2266
  "/audit/timeline": {
2221
2267
  get: {
2222
2268
  tags: ["Auditoria"],
@@ -3091,6 +3137,13 @@ var OPENAPI_SPEC = {
3091
3137
 
3092
3138
  // ../../src/lib/apiScopes.ts
3093
3139
  var API_MODULES = [
3140
+ {
3141
+ key: "documents",
3142
+ label: "Documentos",
3143
+ permissions: [
3144
+ { key: "read", label: "Analisar documentos", description: "Ler anexos (boleto, guia, NF) e extrair valor, vencimento e emitente" }
3145
+ ]
3146
+ },
3094
3147
  {
3095
3148
  key: "customers",
3096
3149
  label: "Clientes",
@@ -3415,6 +3468,22 @@ function augmentInputSchema(schema, opts) {
3415
3468
  }
3416
3469
  return { ...schema, properties };
3417
3470
  }
3471
+ function coerceObjectArg(value) {
3472
+ if (value && typeof value === "object" && !Array.isArray(value)) {
3473
+ return value;
3474
+ }
3475
+ if (typeof value === "string" && value.trim()) {
3476
+ try {
3477
+ const parsed = JSON.parse(value);
3478
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
3479
+ return parsed;
3480
+ }
3481
+ } catch {
3482
+ return void 0;
3483
+ }
3484
+ }
3485
+ return void 0;
3486
+ }
3418
3487
  function destructiveBlocked(args) {
3419
3488
  if (args.confirm === true) return null;
3420
3489
  return fail(
@@ -3463,7 +3532,7 @@ function buildCuratedTools(api, heldScopes) {
3463
3532
  if (blocked && args.dry_run !== true) return blocked;
3464
3533
  }
3465
3534
  const path = buildPath(desc, args);
3466
- const body = desc.hasBody ? args.body : void 0;
3535
+ const body = desc.hasBody ? coerceObjectArg(args.body) : void 0;
3467
3536
  if (args.dry_run === true) {
3468
3537
  return ok({
3469
3538
  dry_run: true,
@@ -3527,15 +3596,16 @@ function buildRequestTool(api) {
3527
3596
  }
3528
3597
  let path = String(args.path ?? "");
3529
3598
  if (!path.startsWith("/")) return fail("path deve come\xE7ar com / (ex.: /customers).");
3530
- if (args.query && typeof args.query === "object") {
3599
+ const queryArg = coerceObjectArg(args.query);
3600
+ if (queryArg) {
3531
3601
  const u = new URLSearchParams();
3532
- for (const [k, v] of Object.entries(args.query)) {
3602
+ for (const [k, v] of Object.entries(queryArg)) {
3533
3603
  if (v !== void 0 && v !== null && v !== "") u.set(k, String(v));
3534
3604
  }
3535
3605
  const s = u.toString();
3536
3606
  if (s) path += (path.includes("?") ? "&" : "?") + s;
3537
3607
  }
3538
- const body = args.body && typeof args.body === "object" ? args.body : void 0;
3608
+ const body = coerceObjectArg(args.body);
3539
3609
  if (args.dry_run === true) {
3540
3610
  return ok({ dry_run: true, method, path, body: body ?? null });
3541
3611
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comando.one/mcp-server",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Servidor MCP (Model Context Protocol) para a API pública do Comando.One — opere seu ERP por linguagem natural.",
5
5
  "type": "module",
6
6
  "license": "MIT",