@comando.one/mcp-server 0.4.0 → 0.5.0

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.
Files changed (3) hide show
  1. package/README.md +6 -2
  2. package/dist/index.js +219 -20
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -39,7 +39,7 @@ Além deste pacote stdio, existe um **endpoint MCP remoto (streaming)** em `http
39
39
  }
40
40
  ```
41
41
 
42
- Ambos expõem o **mesmo conjunto de ferramentas** (50 curadas + `lookups` + `comando_request` = cobertura total da API).
42
+ Ambos expõem o **mesmo conjunto de ferramentas** (131 curadas + `lookups` + `comando_request` = cobertura total da API).
43
43
 
44
44
  ## Variáveis de ambiente
45
45
 
@@ -51,10 +51,14 @@ Ambos expõem o **mesmo conjunto de ferramentas** (50 curadas + `lookups` + `com
51
51
 
52
52
  ## Como funciona
53
53
 
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.
54
+ - **131 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.
58
+ - **Nomes em português** — cada tool viaja com `title` (e `annotations.title`) vindo do
59
+ `summary` da OpenAPI, então o cliente mostra "Listar clientes" em vez de "Customers list".
60
+ O servidor também se identifica com `title` ("Comando.One"), `description`, `websiteUrl` e
61
+ `icons` (SEP-973). Clientes que ainda não leem esses campos caem no nome técnico sem quebrar.
58
62
 
59
63
  ### Segurança
60
64
 
package/dist/index.js CHANGED
@@ -143,6 +143,8 @@ var MANIFEST = [
143
143
  { operationId: "getInvoice", tool: "invoices_get" },
144
144
  { operationId: "createInvoice", tool: "invoices_create", write: true },
145
145
  { operationId: "cancelInvoice", tool: "invoices_cancel", write: true, destructive: true },
146
+ { operationId: "sendInvoiceSecondCopy", tool: "invoices_send", write: true },
147
+ { operationId: "generateContractInvoices", tool: "contracts_generate_invoices", write: true },
146
148
  // ----- Cobranças -----
147
149
  { operationId: "listCharges", tool: "charges_list" },
148
150
  { operationId: "getCharge", tool: "charges_get" },
@@ -194,6 +196,7 @@ var MANIFEST = [
194
196
  { operationId: "releaseSplitItem", tool: "split_release_item", write: true },
195
197
  // Auditoria
196
198
  { operationId: "analyzeDocument", tool: "documents_analyze", write: true },
199
+ { operationId: "listDocuments", tool: "documents_search" },
197
200
  { operationId: "getAuditTimeline", tool: "audit_timeline" },
198
201
  // Categorias de serviço
199
202
  { operationId: "listServiceCategories", tool: "service_categories_list" },
@@ -367,7 +370,7 @@ var SCHEMAS = {
367
370
  email: { type: ["string", "null"] },
368
371
  phone: { type: ["string", "null"] },
369
372
  document: { type: ["string", "null"], description: "CPF ou CNPJ" },
370
- type: { type: "string", enum: ["fisica", "juridica", "estrangeira"] },
373
+ type: { type: "string", enum: ["fisica", "juridica", "estrangeira"], description: "Natureza JUR\xCDDICA do cadastro, n\xE3o a categoria de atividade: fisica = pessoa f\xEDsica (CPF); juridica = pessoa jur\xEDdica (CNPJ), o que inclui empresas, \xF3rg\xE3os p\xFAblicos, prefeituras e a Receita Federal; estrangeira = sem CNPJ/CPF. Na d\xFAvida, OMITA o campo \u2014 o padr\xE3o j\xE1 cobre o caso comum." },
371
374
  company_name: { type: ["string", "null"] },
372
375
  trade_name: { type: ["string", "null"] },
373
376
  status: { type: "string" },
@@ -383,7 +386,7 @@ var SCHEMAS = {
383
386
  email: { type: "string" },
384
387
  phone: { type: "string" },
385
388
  document: { type: "string" },
386
- type: { type: "string", enum: ["fisica", "juridica", "estrangeira"], default: "fisica" },
389
+ type: { type: "string", enum: ["fisica", "juridica", "estrangeira"], default: "fisica", description: "Natureza JUR\xCDDICA do cadastro, n\xE3o a categoria de atividade: fisica = pessoa f\xEDsica (CPF); juridica = pessoa jur\xEDdica (CNPJ), o que inclui empresas, \xF3rg\xE3os p\xFAblicos, prefeituras e a Receita Federal; estrangeira = sem CNPJ/CPF. Na d\xFAvida, OMITA o campo \u2014 o padr\xE3o j\xE1 cobre o caso comum." },
387
390
  company_name: { type: "string" },
388
391
  trade_name: { type: "string" },
389
392
  status: { type: "string", default: "ativo" }
@@ -396,7 +399,7 @@ var SCHEMAS = {
396
399
  email: { type: ["string", "null"] },
397
400
  phone: { type: ["string", "null"] },
398
401
  document: { type: ["string", "null"] },
399
- type: { type: "string", enum: ["fisica", "juridica", "estrangeira"] },
402
+ type: { type: "string", enum: ["fisica", "juridica", "estrangeira"], description: "Natureza JUR\xCDDICA do cadastro, n\xE3o a categoria de atividade: fisica = pessoa f\xEDsica (CPF); juridica = pessoa jur\xEDdica (CNPJ), o que inclui empresas, \xF3rg\xE3os p\xFAblicos, prefeituras e a Receita Federal; estrangeira = sem CNPJ/CPF. Na d\xFAvida, OMITA o campo \u2014 o padr\xE3o j\xE1 cobre o caso comum." },
400
403
  company_name: { type: ["string", "null"] },
401
404
  trade_name: { type: ["string", "null"] },
402
405
  status: { type: "string" }
@@ -685,7 +688,7 @@ var SCHEMAS = {
685
688
  email: { type: ["string", "null"] },
686
689
  phone: { type: ["string", "null"] },
687
690
  document: { type: ["string", "null"], description: "CPF ou CNPJ" },
688
- type: { type: "string", enum: ["fisica", "juridica", "estrangeira"] },
691
+ type: { type: "string", enum: ["fisica", "juridica", "estrangeira"], description: "Natureza JUR\xCDDICA do cadastro, n\xE3o a categoria de atividade: fisica = pessoa f\xEDsica (CPF); juridica = pessoa jur\xEDdica (CNPJ), o que inclui empresas, \xF3rg\xE3os p\xFAblicos, prefeituras e a Receita Federal; estrangeira = sem CNPJ/CPF. Na d\xFAvida, OMITA o campo \u2014 o padr\xE3o j\xE1 cobre o caso comum." },
689
692
  company_name: { type: ["string", "null"] },
690
693
  trade_name: { type: ["string", "null"] },
691
694
  state_registration: { type: ["string", "null"] },
@@ -710,7 +713,7 @@ var SCHEMAS = {
710
713
  email: { type: "string" },
711
714
  phone: { type: "string" },
712
715
  document: { type: "string" },
713
- type: { type: "string", enum: ["fisica", "juridica", "estrangeira"], default: "juridica" },
716
+ type: { type: "string", enum: ["fisica", "juridica", "estrangeira"], default: "juridica", description: "Natureza JUR\xCDDICA do cadastro, n\xE3o a categoria de atividade: fisica = pessoa f\xEDsica (CPF); juridica = pessoa jur\xEDdica (CNPJ), o que inclui empresas, \xF3rg\xE3os p\xFAblicos, prefeituras e a Receita Federal; estrangeira = sem CNPJ/CPF. Na d\xFAvida, OMITA o campo \u2014 o padr\xE3o j\xE1 cobre o caso comum." },
714
717
  company_name: { type: "string" },
715
718
  trade_name: { type: "string" },
716
719
  state_registration: { type: "string" },
@@ -780,7 +783,12 @@ var SCHEMAS = {
780
783
  status: { type: "string", enum: ["pendente", "pago", "cancelado"], default: "pendente" },
781
784
  bank_account_id: { type: "string", format: "uuid" },
782
785
  payment_method_id: { type: "string", format: "uuid" },
783
- notes: { type: "string" }
786
+ notes: { type: "string" },
787
+ attachment_ids: {
788
+ type: "array",
789
+ items: { type: "string", format: "uuid" },
790
+ description: "Ids de anexos j\xE1 enviados que devem ser vinculados \xE0 despesa criada. \xC9 o fluxo 'lance esse imposto e anexe o PDF' numa chamada s\xF3."
791
+ }
784
792
  }
785
793
  },
786
794
  PurchaseInvoice: {
@@ -861,7 +869,12 @@ var SCHEMAS = {
861
869
  title: { type: "string", description: "Descri\xE7\xE3o da fatura; vira o nome do item quando 'items' n\xE3o \xE9 informado." },
862
870
  digitable_line: { type: "string", description: "Atalho: grava o boleto na parcela \xFAnica criada por 'due_date'." },
863
871
  pix_key: { type: "string", description: "Atalho: grava a chave Pix na parcela \xFAnica." },
864
- notes: { type: "string" }
872
+ notes: { type: "string" },
873
+ attachment_ids: {
874
+ type: "array",
875
+ items: { type: "string", format: "uuid" },
876
+ description: "Ids de anexos j\xE1 enviados que devem ser vinculados \xE0 fatura criada. \xC9 o fluxo 'lance esse imposto e anexe o PDF' numa chamada s\xF3."
877
+ }
865
878
  }
866
879
  },
867
880
  Charge: {
@@ -872,7 +885,7 @@ var SCHEMAS = {
872
885
  status: { type: "string", enum: ["pending", "paid", "cancelled", "expired", "failed"] },
873
886
  status_raw: { type: "string", description: "Status bruto do provider" },
874
887
  method: { type: "string", enum: ["pix", "boleto", "checkout", "credit_card"] },
875
- provider: { type: "string", enum: ["inter", "c6bank", "pix_offline", "pagarme"], description: "Provedor resolvido. 'pix_offline' = Pix est\xE1tico (BR Code local). 'pagarme' = Pix server-side ou cart\xE3o (method=credit_card retorna 'checkout.url' = link da p\xE1gina de pagamento)." },
888
+ provider: { type: "string", enum: ["inter", "c6bank", "pix_offline", "pagarme", "cora"], description: "Provedor resolvido. 'pix_offline' = Pix est\xE1tico (BR Code local). 'pagarme' = Pix server-side ou cart\xE3o (method=credit_card retorna 'checkout.url' = link da p\xE1gina de pagamento). 'cora' = boleto ou Pix emitidos de forma s\xEDncrona (o boleto j\xE1 volta com 'pdf_url')." },
876
889
  invoice_id: { type: ["string", "null"], format: "uuid" },
877
890
  customer_id: { type: ["string", "null"], format: "uuid" },
878
891
  amount: { type: ["number", "null"] },
@@ -889,7 +902,7 @@ var SCHEMAS = {
889
902
  required: ["method"],
890
903
  properties: {
891
904
  method: { type: "string", enum: ["pix", "boleto", "checkout", "credit_card"], description: "Canal de pagamento" },
892
- provider: { type: "string", enum: ["inter", "c6bank", "pix_offline", "pagarme"], description: "Opcional. Desambigua quando a empresa tem mais de um provedor no mesmo canal (ex.: Pix Inter x Pix Pagar.me). Se omitido, usa o provedor ativo do canal." },
905
+ provider: { type: "string", enum: ["inter", "c6bank", "pix_offline", "pagarme", "cora"], description: "Opcional. Desambigua quando a empresa tem mais de um provedor no mesmo canal (ex.: Pix Inter x Pix Pagar.me x Pix Cora). Se omitido, usa o provedor ativo do canal." },
893
906
  invoice_id: { type: "string", format: "uuid", description: "Fatura existente (opcional)" },
894
907
  customer_id: { type: "string", format: "uuid", description: "Obrigat\xF3rio se invoice_id omitido" },
895
908
  amount: { type: "number", description: "Obrigat\xF3rio se invoice_id omitido" },
@@ -1977,6 +1990,9 @@ var OPENAPI_SPEC = {
1977
1990
  { name: "payment_status", in: "query", schema: { type: "string", enum: ["pendente", "parcial", "pago", "vencido"] } },
1978
1991
  { name: "customer_id", in: "query", schema: { type: "string", format: "uuid" } },
1979
1992
  { name: "due_date_from", in: "query", schema: { type: "string", format: "date" }, description: "Vencimento a partir de (YYYY-MM-DD)" },
1993
+ { name: "overdue", in: "query", schema: { type: "string", enum: ["true", "false"] }, description: "true = vencidas de VERDADE (vencimento passado e n\xE3o pagas). N\xE3o confunda com payment_status=vencido: esse campo \xE9 agregado e 'parcial' ganha de 'vencido', ent\xE3o uma fatura com parcela paga e parcela vencida N\xC3O aparece l\xE1. Para cobran\xE7a, use este filtro." },
1994
+ { name: "sort_by", in: "query", description: "Coluna de ordena\xE7\xE3o. Use com sort_order para responder 'as maiores' ou 'as mais recentes'.", schema: { type: "string", enum: ["amount", "due_date", "created_at", "updated_at", "invoice_number"] } },
1995
+ { name: "sort_order", in: "query", description: "Dire\xE7\xE3o da ordena\xE7\xE3o. Padr\xE3o: desc quando sort_by \xE9 informado.", schema: { type: "string", enum: ["asc", "desc"] } },
1980
1996
  { name: "due_date_to", in: "query", schema: { type: "string", format: "date" }, description: "Vencimento at\xE9 (YYYY-MM-DD)" }
1981
1997
  ],
1982
1998
  responses: {
@@ -2016,6 +2032,83 @@ var OPENAPI_SPEC = {
2016
2032
  responses: { "204": { description: "Exclu\xEDda" }, "404": errorResponse("Fatura n\xE3o encontrada"), "409": errorResponse("H\xE1 registros vinculados que impedem a exclus\xE3o"), ...COMMON_ERRORS }
2017
2033
  }
2018
2034
  },
2035
+ "/contracts/{id}/generate-invoices": {
2036
+ parameters: [{ name: "id", in: "path", required: true, schema: { type: "string", format: "uuid" } }],
2037
+ post: {
2038
+ tags: ["Contratos"],
2039
+ summary: "Gerar as faturas devidas do contrato",
2040
+ operationId: "generateContractInvoices",
2041
+ description: "Gera as faturas em aberto do contrato conforme a periodicidade dele. A regra de compet\xEAncia (e a prote\xE7\xE3o contra duplicar fatura do mesmo per\xEDodo) \xE9 da rotina de gera\xE7\xE3o, n\xE3o deste endpoint.",
2042
+ security: [{ ApiKeyAuth: ["invoices:create"] }],
2043
+ responses: {
2044
+ "200": {
2045
+ description: "Gera\xE7\xE3o executada",
2046
+ content: {
2047
+ "application/json": {
2048
+ schema: {
2049
+ type: "object",
2050
+ properties: {
2051
+ contract_id: { type: "string", format: "uuid" },
2052
+ created: { type: "integer", description: "Quantas faturas nasceram nesta chamada." }
2053
+ }
2054
+ }
2055
+ }
2056
+ }
2057
+ },
2058
+ ...COMMON_ERRORS
2059
+ }
2060
+ }
2061
+ },
2062
+ "/invoices/{id}/send": {
2063
+ parameters: [{ name: "id", in: "path", required: true, schema: { type: "string", format: "uuid" } }],
2064
+ post: {
2065
+ tags: ["Faturas"],
2066
+ summary: "Enviar segunda via da fatura ao cliente",
2067
+ operationId: "sendInvoiceSecondCopy",
2068
+ description: "Envia a segunda via por e-mail. Sem 'to', usa o e-mail cadastrado do cliente. Os anexos da fatura v\xE3o junto por padr\xE3o. Registra a tentativa na fila de e-mails antes de enviar, ent\xE3o um envio que falha deixa rastro.",
2069
+ security: [{ ApiKeyAuth: ["invoices:send"] }],
2070
+ requestBody: {
2071
+ required: false,
2072
+ content: {
2073
+ "application/json": {
2074
+ schema: {
2075
+ type: "object",
2076
+ properties: {
2077
+ to: {
2078
+ description: "Destinat\xE1rio(s). Aceita string separada por v\xEDrgula ou lista. Omitido, usa o e-mail do cliente.",
2079
+ oneOf: [{ type: "string" }, { type: "array", items: { type: "string", format: "email" } }]
2080
+ },
2081
+ subject: { type: "string", description: "Assunto. Padr\xE3o: 'Segunda via da fatura <numero>'." },
2082
+ body_html: { type: "string", description: "Corpo em HTML. Padr\xE3o: mensagem curta com valor e vencimento." },
2083
+ include_attachments: { type: "boolean", default: true, description: "Anexa os arquivos da fatura." }
2084
+ }
2085
+ }
2086
+ }
2087
+ }
2088
+ },
2089
+ responses: {
2090
+ "200": {
2091
+ description: "Segunda via enviada",
2092
+ content: {
2093
+ "application/json": {
2094
+ schema: {
2095
+ type: "object",
2096
+ properties: {
2097
+ invoice_id: { type: "string", format: "uuid" },
2098
+ schedule_id: { type: "string", format: "uuid" },
2099
+ recipients: { type: "array", items: { type: "string" } },
2100
+ subject: { type: "string" },
2101
+ attachments: { type: "integer" },
2102
+ sent_at: { type: "string", format: "date-time" }
2103
+ }
2104
+ }
2105
+ }
2106
+ }
2107
+ },
2108
+ ...COMMON_ERRORS
2109
+ }
2110
+ }
2111
+ },
2019
2112
  "/invoices/{id}/cancel": {
2020
2113
  parameters: [{ name: "id", in: "path", required: true, schema: { type: "string", format: "uuid" } }],
2021
2114
  patch: {
@@ -2241,6 +2334,52 @@ var OPENAPI_SPEC = {
2241
2334
  responses: { "200": paginatedResponse("#/components/schemas/ServiceUnit"), ...COMMON_ERRORS }
2242
2335
  }
2243
2336
  },
2337
+ "/documents": {
2338
+ get: {
2339
+ tags: ["Documentos"],
2340
+ summary: "Procurar anexos j\xE1 enviados",
2341
+ operationId: "listDocuments",
2342
+ description: "Busca anexos da empresa por nome do arquivo e/ou entidade a que est\xE3o ligados. Ordenado do mais recente para o mais antigo \u2014 \xE9 o que 'aquele boleto que mandei' quer dizer na pr\xE1tica.",
2343
+ security: [{ ApiKeyAuth: ["documents:read"] }],
2344
+ parameters: [
2345
+ ...PAGINATION_PARAMS,
2346
+ { name: "search", in: "query", schema: { type: "string" }, description: "Trecho do nome do arquivo." },
2347
+ { name: "entity_type", in: "query", schema: { type: "string", enum: ["invoice", "purchase_invoice", "expense", "proposal", "contract", "customer", "supplier", "payment", "supplier_payment", "agent_message"] } },
2348
+ { name: "entity_id", in: "query", schema: { type: "string", format: "uuid" }, description: "Anexos de um registro espec\xEDfico." }
2349
+ ],
2350
+ responses: {
2351
+ "200": {
2352
+ description: "Anexos encontrados",
2353
+ content: {
2354
+ "application/json": {
2355
+ schema: {
2356
+ type: "object",
2357
+ properties: {
2358
+ data: {
2359
+ type: "array",
2360
+ items: {
2361
+ type: "object",
2362
+ properties: {
2363
+ id: { type: "string", format: "uuid" },
2364
+ entity_type: { type: "string" },
2365
+ entity_id: { type: "string", format: "uuid", nullable: true },
2366
+ file_name: { type: "string" },
2367
+ file_path: { type: "string" },
2368
+ file_size: { type: "integer" },
2369
+ mime_type: { type: "string", nullable: true },
2370
+ created_at: { type: "string", format: "date-time" }
2371
+ }
2372
+ }
2373
+ }
2374
+ }
2375
+ }
2376
+ }
2377
+ }
2378
+ },
2379
+ ...COMMON_ERRORS
2380
+ }
2381
+ }
2382
+ },
2244
2383
  "/documents/analyze": {
2245
2384
  post: {
2246
2385
  tags: ["Documentos"],
@@ -2325,7 +2464,7 @@ var OPENAPI_SPEC = {
2325
2464
  summary: "Listar categorias de servi\xE7o",
2326
2465
  operationId: "listServiceCategories",
2327
2466
  security: [{ ApiKeyAuth: ["services:read"] }],
2328
- parameters: [...PAGINATION_PARAMS, { name: "search", in: "query", schema: { type: "string" }, description: "Filtro por nome (ilike)" }],
2467
+ parameters: [...PAGINATION_PARAMS, { name: "search", in: "query", schema: { type: "string" }, description: "Filtro por nome (ilike)" }, { name: "query", in: "query", schema: { type: "string" }, description: "Apelido de 'search' \u2014 o c\xF3digo j\xE1 aceitava os dois nomes; agora est\xE1 documentado." }],
2329
2468
  responses: { "200": paginatedResponse("#/components/schemas/ServiceCategory"), ...COMMON_ERRORS }
2330
2469
  },
2331
2470
  post: {
@@ -2370,14 +2509,30 @@ var OPENAPI_SPEC = {
2370
2509
  { name: "min_overdue_days", in: "query", schema: { type: "integer", minimum: 1, maximum: 365, default: 1 } },
2371
2510
  { name: "include_shared", in: "query", schema: { type: "boolean", default: true }, description: "Incluir clientes compartilhados" },
2372
2511
  { name: "customer_id", in: "query", schema: { type: "string", format: "uuid" } },
2373
- { name: "search", in: "query", schema: { type: "string" } }
2512
+ { name: "search", in: "query", schema: { type: "string" } },
2513
+ { name: "query", in: "query", schema: { type: "string" }, description: "Apelido de 'search' \u2014 o c\xF3digo j\xE1 aceitava os dois nomes; agora est\xE1 documentado." }
2374
2514
  ],
2375
2515
  responses: { "200": { description: "Faturas em atraso + a\xE7\xF5es recomendadas", content: { "application/json": { schema: { type: "object", properties: {
2376
2516
  count: { type: "integer" },
2377
2517
  limit: { type: "integer" },
2378
2518
  min_overdue_days: { type: "integer" },
2379
- total_overdue_amount: { type: "number" },
2380
- actions: { type: "array", items: { type: "object" } }
2519
+ total_overdue_amount: { type: "number", description: "Soma do SALDO em aberto (valor da fatura menos o que j\xE1 foi pago) \u2014 o que ainda d\xE1 para cobrar." },
2520
+ total_invoiced_amount: { type: "number", description: "Soma do valor cheio das mesmas faturas, ignorando pagamentos parciais." },
2521
+ actions: { type: "array", items: { type: "object", properties: {
2522
+ invoice_id: { type: "string", format: "uuid" },
2523
+ invoice_number: { type: "string", nullable: true },
2524
+ title: { type: "string", nullable: true },
2525
+ customer_id: { type: "string", format: "uuid" },
2526
+ customer_name: { type: "string", nullable: true },
2527
+ amount: { type: "number", description: "Valor cheio da fatura." },
2528
+ paid_amount: { type: "number", description: "Quanto j\xE1 foi pago nesta fatura." },
2529
+ outstanding_amount: { type: "number", description: "Saldo devedor \u2014 \xE9 este o valor a cobrar." },
2530
+ due_date: { type: "string", format: "date", nullable: true },
2531
+ payment_status: { type: "string" },
2532
+ status: { type: "string" },
2533
+ days_overdue: { type: "integer" },
2534
+ recommended_action: { type: "string" }
2535
+ } } }
2381
2536
  } } } } }, ...COMMON_ERRORS }
2382
2537
  }
2383
2538
  },
@@ -2591,7 +2746,9 @@ var OPENAPI_SPEC = {
2591
2746
  { name: "supplier_id", in: "query", schema: { type: "string", format: "uuid" } },
2592
2747
  { name: "category_id", in: "query", schema: { type: "string", format: "uuid" } },
2593
2748
  { name: "expense_date_from", in: "query", schema: { type: "string", format: "date" } },
2594
- { name: "expense_date_to", in: "query", schema: { type: "string", format: "date" } }
2749
+ { name: "expense_date_to", in: "query", schema: { type: "string", format: "date" } },
2750
+ { name: "sort_by", in: "query", description: "Coluna de ordena\xE7\xE3o. Use com sort_order para responder 'as maiores' ou 'as mais recentes'.", schema: { type: "string", enum: ["amount", "expense_date", "due_date", "created_at", "updated_at"] } },
2751
+ { name: "sort_order", in: "query", description: "Dire\xE7\xE3o da ordena\xE7\xE3o. Padr\xE3o: desc quando sort_by \xE9 informado.", schema: { type: "string", enum: ["asc", "desc"] } }
2595
2752
  ],
2596
2753
  responses: { "200": paginatedResponse("#/components/schemas/Expense"), ...COMMON_ERRORS }
2597
2754
  },
@@ -2645,7 +2802,10 @@ var OPENAPI_SPEC = {
2645
2802
  { name: "supplier_id", in: "query", schema: { type: "string", format: "uuid" } },
2646
2803
  { name: "invoice_number", in: "query", schema: { type: "string" } },
2647
2804
  { name: "due_date_from", in: "query", schema: { type: "string", format: "date" } },
2648
- { name: "due_date_to", in: "query", schema: { type: "string", format: "date" } }
2805
+ { name: "due_date_to", in: "query", schema: { type: "string", format: "date" } },
2806
+ { name: "overdue", in: "query", schema: { type: "string", enum: ["true", "false"] }, description: "true = contas a pagar com parcela vencida e n\xE3o paga. O vencimento mora nas parcelas, ent\xE3o o status agregado da fatura n\xE3o responde isso." },
2807
+ { name: "sort_by", in: "query", description: "Coluna de ordena\xE7\xE3o. Use com sort_order para responder 'as maiores' ou 'as mais recentes'.", schema: { type: "string", enum: ["amount", "issue_date", "created_at", "updated_at", "invoice_number"] } },
2808
+ { name: "sort_order", in: "query", description: "Dire\xE7\xE3o da ordena\xE7\xE3o. Padr\xE3o: desc quando sort_by \xE9 informado.", schema: { type: "string", enum: ["asc", "desc"] } }
2649
2809
  ],
2650
2810
  responses: { "200": paginatedResponse("#/components/schemas/PurchaseInvoice"), ...COMMON_ERRORS }
2651
2811
  },
@@ -2700,7 +2860,9 @@ var OPENAPI_SPEC = {
2700
2860
  { name: "status", in: "query", schema: { type: "string", enum: ["pending", "paid", "cancelled", "expired", "failed"] } },
2701
2861
  { name: "method", in: "query", schema: { type: "string", enum: ["pix", "boleto", "checkout", "credit_card"] } },
2702
2862
  { name: "customer_id", in: "query", schema: { type: "string", format: "uuid" } },
2703
- { name: "invoice_id", in: "query", schema: { type: "string", format: "uuid" } }
2863
+ { name: "invoice_id", in: "query", schema: { type: "string", format: "uuid" } },
2864
+ { name: "sort_by", in: "query", description: "Coluna de ordena\xE7\xE3o. Use com sort_order para responder 'as maiores' ou 'as mais recentes'.", schema: { type: "string", enum: ["amount", "due_date", "created_at", "paid_at"] } },
2865
+ { name: "sort_order", in: "query", description: "Dire\xE7\xE3o da ordena\xE7\xE3o. Padr\xE3o: desc quando sort_by \xE9 informado.", schema: { type: "string", enum: ["asc", "desc"] } }
2704
2866
  ],
2705
2867
  responses: { "200": paginatedResponse("#/components/schemas/Charge"), ...COMMON_ERRORS }
2706
2868
  },
@@ -3143,7 +3305,8 @@ var OPENAPI_SPEC = {
3143
3305
  ...PAGINATION_PARAMS,
3144
3306
  { name: "active", in: "query", schema: { type: "string", enum: ["true", "false"] } },
3145
3307
  { name: "provider", in: "query", schema: { type: "string", enum: ["inter", "c6bank"] } },
3146
- { name: "channel", in: "query", schema: { type: "string", enum: ["pix", "boleto", "checkout", "credit_card"] } }
3308
+ { name: "channel", in: "query", schema: { type: "string", enum: ["pix", "boleto", "checkout", "credit_card"] } },
3309
+ { name: "all", in: "query", description: "true lista TODAS as formas cadastradas; por padr\xE3o s\xF3 as utiliz\xE1veis (manuais ou de provider com integra\xE7\xE3o ativa).", schema: { type: "string", enum: ["true", "false"] } }
3147
3310
  ],
3148
3311
  responses: { "200": paginatedResponse("#/components/schemas/PaymentMethod"), ...COMMON_ERRORS }
3149
3312
  }
@@ -3201,6 +3364,7 @@ var API_MODULES = [
3201
3364
  { key: "read", label: "Listar e visualizar", description: "Consultar faturas e cobran\xE7as" },
3202
3365
  { key: "create", label: "Criar cobran\xE7a", description: "Gerar boletos, Pix e cobran\xE7as" },
3203
3366
  { key: "cancel", label: "Cancelar cobran\xE7a", description: "Cancelar cobran\xE7as em aberto" },
3367
+ { key: "send", label: "Enviar ao cliente", description: "Enviar segunda via da fatura por e-mail ao cliente" },
3204
3368
  { key: "delete", label: "Excluir fatura", description: "Excluir faturas permanentemente (itens e cobran\xE7as vinculadas)" }
3205
3369
  ]
3206
3370
  },
@@ -3433,7 +3597,6 @@ function describeOperation(operationId) {
3433
3597
  scopes: extractScopes(operation),
3434
3598
  inputSchema,
3435
3599
  summary: operation.summary,
3436
- description: operation.description,
3437
3600
  description: operation.description
3438
3601
  };
3439
3602
  }
@@ -3558,6 +3721,9 @@ function buildCuratedTools(api, heldScopes) {
3558
3721
  const description = `${prefix}${desc.summary ?? entry.operationId}.${scopeNote}`;
3559
3722
  tools.push({
3560
3723
  name: entry.tool,
3724
+ // O `summary` da OpenAPI já é escrito em português — é ele que vira o rótulo no
3725
+ // cliente. Sem isso o Claude Desktop humaniza o nome técnico ("Customers list").
3726
+ title: desc.summary?.trim() || void 0,
3561
3727
  description,
3562
3728
  inputSchema: asInputSchema(inputSchema),
3563
3729
  handler: async (args) => {
@@ -3596,6 +3762,7 @@ var METHODS = ["GET", "POST", "PATCH", "PUT", "DELETE"];
3596
3762
  function buildRequestTool(api) {
3597
3763
  return {
3598
3764
  name: "comando_request",
3765
+ title: "Chamada livre \xE0 API",
3599
3766
  description: "Chamada gen\xE9rica \xE0 API do Comando.One (cobre qualquer endpoint /v1/*). Use quando n\xE3o houver uma tool espec\xEDfica. Ex.: method=GET, path=/webhooks/deliveries. Os scopes da chave s\xE3o validados pelo servidor.",
3600
3767
  inputSchema: {
3601
3768
  type: "object",
@@ -3670,6 +3837,7 @@ var KINDS = {
3670
3837
  function buildLookupsTool(api) {
3671
3838
  return {
3672
3839
  name: "lookups",
3840
+ title: "Consultar cat\xE1logos",
3673
3841
  description: "Consulta cat\xE1logos read-only do ERP: centros de custo, condi\xE7\xF5es/m\xE9todos de pagamento, unidades de servi\xE7o, naturezas financeiras e contas banc\xE1rias.",
3674
3842
  inputSchema: {
3675
3843
  type: "object",
@@ -3710,6 +3878,7 @@ function buildLookupsTool(api) {
3710
3878
  function buildWhoamiTool(api) {
3711
3879
  return {
3712
3880
  name: "whoami",
3881
+ title: "Identidade da chave",
3713
3882
  description: "Retorna a identidade da chave de API: empresa atual, empresas acess\xEDveis, scopes concedidos e se \xE9 multi-empresa.",
3714
3883
  inputSchema: { type: "object", properties: {} },
3715
3884
  handler: async () => {
@@ -3722,6 +3891,20 @@ function buildWhoamiTool(api) {
3722
3891
  };
3723
3892
  }
3724
3893
 
3894
+ // src/branding.ts
3895
+ var MCP_SERVER_NAME = "comando-one";
3896
+ var MCP_SERVER_TITLE = "Comando.One";
3897
+ var MCP_SERVER_VERSION = "0.5.0";
3898
+ var MCP_SERVER_DESCRIPTION = "ERP das empresas de servi\xE7o brasileiras: clientes, propostas, contratos, faturas, cobran\xE7as Pix e boleto, NFS-e, contas a pagar e financeiro.";
3899
+ var MCP_SERVER_WEBSITE = "https://comando.one";
3900
+ var MCP_SERVER_ICONS = [
3901
+ {
3902
+ src: "data:image/png;base64,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",
3903
+ mimeType: "image/png",
3904
+ sizes: ["96x96"]
3905
+ }
3906
+ ];
3907
+
3725
3908
  // src/index.ts
3726
3909
  function loadDotEnv() {
3727
3910
  try {
@@ -3774,11 +3957,27 @@ async function main() {
3774
3957
  `
3775
3958
  );
3776
3959
  const server = new Server(
3777
- { name: "comando-one", version: "0.1.0" },
3960
+ {
3961
+ name: MCP_SERVER_NAME,
3962
+ // `title` é o nome que o app mostra; `icons` é a marca no lugar da inicial genérica.
3963
+ title: MCP_SERVER_TITLE,
3964
+ version: MCP_SERVER_VERSION,
3965
+ description: MCP_SERVER_DESCRIPTION,
3966
+ websiteUrl: MCP_SERVER_WEBSITE,
3967
+ icons: MCP_SERVER_ICONS
3968
+ },
3778
3969
  { capabilities: { tools: {} } }
3779
3970
  );
3780
3971
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
3781
- tools: tools.map((t) => ({ name: t.name, description: t.description, inputSchema: t.inputSchema }))
3972
+ // `title` e `annotations.title` juntos: revisões mais novas do protocolo leem o
3973
+ // primeiro, as anteriores leem o segundo. Sem nenhum dos dois o cliente cai no nome
3974
+ // técnico em inglês.
3975
+ tools: tools.map((t) => ({
3976
+ name: t.name,
3977
+ ...t.title ? { title: t.title, annotations: { title: t.title } } : {},
3978
+ description: t.description,
3979
+ inputSchema: t.inputSchema
3980
+ }))
3782
3981
  }));
3783
3982
  server.setRequestHandler(CallToolRequestSchema, async (req) => {
3784
3983
  const tool = byName.get(req.params.name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comando.one/mcp-server",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
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",