@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 +1 -1
- package/dist/index.js +74 -4
- package/package.json +1 -1
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
|
-
- **
|
|
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
|
-
|
|
3599
|
+
const queryArg = coerceObjectArg(args.query);
|
|
3600
|
+
if (queryArg) {
|
|
3531
3601
|
const u = new URLSearchParams();
|
|
3532
|
-
for (const [k, v] of Object.entries(
|
|
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
|
|
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