@comando.one/mcp-server 0.2.0 → 0.3.1
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 +88 -7
- 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
|
+
- **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.
|
|
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
|
@@ -223,7 +223,65 @@ var MANIFEST = [
|
|
|
223
223
|
{ operationId: "listReminders", tool: "reminders_list" },
|
|
224
224
|
{ operationId: "createReminder", tool: "reminders_create", write: true },
|
|
225
225
|
{ operationId: "updateReminder", tool: "reminders_update", write: true },
|
|
226
|
-
{ operationId: "deleteReminder", tool: "reminders_delete", write: true, destructive: true }
|
|
226
|
+
{ operationId: "deleteReminder", tool: "reminders_delete", write: true, destructive: true },
|
|
227
|
+
// ── Cobertura completa da API (2026-08-14) ──────────────────────────────
|
|
228
|
+
// 43 operações que já existiam na API pública e não tinham tool: um agente
|
|
229
|
+
// conseguia criar cliente mas não editar endereço, listar fatura mas não
|
|
230
|
+
// apagar despesa. Deriva do MANIFEST curado, não decisão de projeto.
|
|
231
|
+
// Flags seguem a convenção: mutação = write; remoção = write + destructive.
|
|
232
|
+
// Identidade e empresa
|
|
233
|
+
{ operationId: "getMe", tool: "me_get" },
|
|
234
|
+
{ operationId: "getCompany", tool: "companies_get" },
|
|
235
|
+
// Clientes — sub-recursos e edição
|
|
236
|
+
{ operationId: "listCustomerAddresses", tool: "customers_list_addresses" },
|
|
237
|
+
{ operationId: "updateCustomerAddress", tool: "customers_update_address", write: true },
|
|
238
|
+
{ operationId: "deleteCustomerAddress", tool: "customers_delete_address", write: true, destructive: true },
|
|
239
|
+
{ operationId: "listCustomerContacts", tool: "customers_list_contacts" },
|
|
240
|
+
{ operationId: "updateCustomerContact", tool: "customers_update_contact", write: true },
|
|
241
|
+
{ operationId: "deleteCustomerContact", tool: "customers_delete_contact", write: true, destructive: true },
|
|
242
|
+
{ operationId: "listCustomerContracts", tool: "customers_list_contracts" },
|
|
243
|
+
{ operationId: "listCustomerProposals", tool: "customers_list_proposals" },
|
|
244
|
+
// Propostas e contratos — edição e exclusão
|
|
245
|
+
{ operationId: "updateProposal", tool: "proposals_update", write: true },
|
|
246
|
+
{ operationId: "deleteProposal", tool: "proposals_delete", write: true, destructive: true },
|
|
247
|
+
{ operationId: "updateContract", tool: "contracts_update", write: true },
|
|
248
|
+
{ operationId: "deleteContract", tool: "contracts_delete", write: true, destructive: true },
|
|
249
|
+
// Fornecedores — edição e formas de pagamento
|
|
250
|
+
{ operationId: "updateSupplier", tool: "suppliers_update", write: true },
|
|
251
|
+
{ operationId: "deleteSupplier", tool: "suppliers_delete", write: true, destructive: true },
|
|
252
|
+
{ operationId: "listSupplierPaymentMethods", tool: "suppliers_list_payment_methods" },
|
|
253
|
+
{ operationId: "createSupplierPaymentMethod", tool: "suppliers_add_payment_method", write: true },
|
|
254
|
+
{ operationId: "updateSupplierPaymentMethod", tool: "suppliers_update_payment_method", write: true },
|
|
255
|
+
{ operationId: "deleteSupplierPaymentMethod", tool: "suppliers_delete_payment_method", write: true, destructive: true },
|
|
256
|
+
// Serviços
|
|
257
|
+
{ operationId: "getService", tool: "services_get" },
|
|
258
|
+
{ operationId: "updateService", tool: "services_update", write: true },
|
|
259
|
+
{ operationId: "deleteService", tool: "services_delete", write: true, destructive: true },
|
|
260
|
+
{ operationId: "listServiceUnits", tool: "service_units_list" },
|
|
261
|
+
// Despesas
|
|
262
|
+
{ operationId: "getExpense", tool: "expenses_get" },
|
|
263
|
+
{ operationId: "updateExpense", tool: "expenses_update", write: true },
|
|
264
|
+
{ operationId: "deleteExpense", tool: "expenses_delete", write: true, destructive: true },
|
|
265
|
+
// Financeiro e contas bancárias
|
|
266
|
+
{ operationId: "listFinancialNatures", tool: "finance_list_natures" },
|
|
267
|
+
{ operationId: "deleteFinancialMovement", tool: "finance_delete_movement", write: true, destructive: true },
|
|
268
|
+
{ operationId: "listBankAccounts", tool: "bank_accounts_list" },
|
|
269
|
+
{ operationId: "getBankAccount", tool: "bank_accounts_get" },
|
|
270
|
+
// Dados de referência de pagamento
|
|
271
|
+
{ operationId: "listPaymentConditions", tool: "payment_conditions_list" },
|
|
272
|
+
{ operationId: "listPaymentMethods", tool: "payment_methods_list" },
|
|
273
|
+
{ operationId: "listPaymentMethodsAp", tool: "payment_methods_ap_list" },
|
|
274
|
+
// Repasses
|
|
275
|
+
{ operationId: "syncPayout", tool: "payouts_sync", write: true },
|
|
276
|
+
// Webhooks — edição, teste e entregas
|
|
277
|
+
{ operationId: "updateWebhook", tool: "webhooks_update", write: true },
|
|
278
|
+
{ operationId: "deleteWebhook", tool: "webhooks_delete", write: true, destructive: true },
|
|
279
|
+
{ operationId: "getWebhook", tool: "webhooks_get_config" },
|
|
280
|
+
{ operationId: "upsertWebhook", tool: "webhooks_upsert_config", write: true },
|
|
281
|
+
{ operationId: "testWebhook", tool: "webhooks_test", write: true },
|
|
282
|
+
{ operationId: "listWebhookDeliveries", tool: "webhooks_list_deliveries" },
|
|
283
|
+
{ operationId: "listWebhookEvents", tool: "webhooks_list_events" },
|
|
284
|
+
{ operationId: "redeliverWebhook", tool: "webhooks_redeliver", write: true }
|
|
227
285
|
];
|
|
228
286
|
|
|
229
287
|
// ../../src/lib/openApiSpec.ts
|
|
@@ -3048,7 +3106,7 @@ var API_MODULES = [
|
|
|
3048
3106
|
permissions: [
|
|
3049
3107
|
{ key: "read", label: "Listar e visualizar", description: "Consultar propostas comerciais" },
|
|
3050
3108
|
{ key: "write", label: "Criar e editar", description: "Criar e editar propostas" },
|
|
3051
|
-
{ key: "send", label: "Enviar", description: "Enviar propostas por e-mail
|
|
3109
|
+
{ key: "send", label: "Enviar", description: "Enviar propostas por e-mail" },
|
|
3052
3110
|
{ key: "delete", label: "Excluir", description: "Excluir propostas" }
|
|
3053
3111
|
]
|
|
3054
3112
|
},
|
|
@@ -3357,6 +3415,22 @@ function augmentInputSchema(schema, opts) {
|
|
|
3357
3415
|
}
|
|
3358
3416
|
return { ...schema, properties };
|
|
3359
3417
|
}
|
|
3418
|
+
function coerceObjectArg(value) {
|
|
3419
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
3420
|
+
return value;
|
|
3421
|
+
}
|
|
3422
|
+
if (typeof value === "string" && value.trim()) {
|
|
3423
|
+
try {
|
|
3424
|
+
const parsed = JSON.parse(value);
|
|
3425
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3426
|
+
return parsed;
|
|
3427
|
+
}
|
|
3428
|
+
} catch {
|
|
3429
|
+
return void 0;
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
return void 0;
|
|
3433
|
+
}
|
|
3360
3434
|
function destructiveBlocked(args) {
|
|
3361
3435
|
if (args.confirm === true) return null;
|
|
3362
3436
|
return fail(
|
|
@@ -3405,7 +3479,7 @@ function buildCuratedTools(api, heldScopes) {
|
|
|
3405
3479
|
if (blocked && args.dry_run !== true) return blocked;
|
|
3406
3480
|
}
|
|
3407
3481
|
const path = buildPath(desc, args);
|
|
3408
|
-
const body = desc.hasBody ? args.body : void 0;
|
|
3482
|
+
const body = desc.hasBody ? coerceObjectArg(args.body) : void 0;
|
|
3409
3483
|
if (args.dry_run === true) {
|
|
3410
3484
|
return ok({
|
|
3411
3485
|
dry_run: true,
|
|
@@ -3452,7 +3526,8 @@ function buildRequestTool(api) {
|
|
|
3452
3526
|
body: { type: "object", description: "Corpo JSON (para POST/PATCH/PUT).", additionalProperties: true },
|
|
3453
3527
|
company_id: { type: "string", description: "Opcional: UUID da empresa (header X-Company-Id)." },
|
|
3454
3528
|
idempotency_key: { type: "string", description: "Opcional: chave de idempot\xEAncia (POST)." },
|
|
3455
|
-
dry_run: { type: "boolean", description: "Se true, n\xE3o executa \u2014 s\xF3 mostra o que seria enviado." }
|
|
3529
|
+
dry_run: { type: "boolean", description: "Se true, n\xE3o executa \u2014 s\xF3 mostra o que seria enviado." },
|
|
3530
|
+
confirm: { type: "boolean", description: "Obrigat\xF3rio para DELETE: confirma a exclus\xE3o." }
|
|
3456
3531
|
}
|
|
3457
3532
|
},
|
|
3458
3533
|
handler: async (args) => {
|
|
@@ -3461,17 +3536,23 @@ function buildRequestTool(api) {
|
|
|
3461
3536
|
if (!METHODS.includes(method)) {
|
|
3462
3537
|
return fail(`M\xE9todo inv\xE1lido: ${args.method}. Use um de: ${METHODS.join(", ")}.`);
|
|
3463
3538
|
}
|
|
3539
|
+
if (method === "DELETE" && args.confirm !== true && args.dry_run !== true) {
|
|
3540
|
+
return fail(
|
|
3541
|
+
"A\xE7\xE3o destrutiva bloqueada. Passe confirm: true para executar, ou dry_run: true para pr\xE9-visualizar."
|
|
3542
|
+
);
|
|
3543
|
+
}
|
|
3464
3544
|
let path = String(args.path ?? "");
|
|
3465
3545
|
if (!path.startsWith("/")) return fail("path deve come\xE7ar com / (ex.: /customers).");
|
|
3466
|
-
|
|
3546
|
+
const queryArg = coerceObjectArg(args.query);
|
|
3547
|
+
if (queryArg) {
|
|
3467
3548
|
const u = new URLSearchParams();
|
|
3468
|
-
for (const [k, v] of Object.entries(
|
|
3549
|
+
for (const [k, v] of Object.entries(queryArg)) {
|
|
3469
3550
|
if (v !== void 0 && v !== null && v !== "") u.set(k, String(v));
|
|
3470
3551
|
}
|
|
3471
3552
|
const s = u.toString();
|
|
3472
3553
|
if (s) path += (path.includes("?") ? "&" : "?") + s;
|
|
3473
3554
|
}
|
|
3474
|
-
const body = args.body
|
|
3555
|
+
const body = coerceObjectArg(args.body);
|
|
3475
3556
|
if (args.dry_run === true) {
|
|
3476
3557
|
return ok({ dry_run: true, method, path, body: body ?? null });
|
|
3477
3558
|
}
|
package/package.json
CHANGED