biaws-mcp 0.9.0 → 0.10.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.
package/README.md CHANGED
@@ -65,13 +65,13 @@ O pacote público expõe o executável `biaws-mcp`. Clientes configurados pelo C
65
65
  usam uma versão fixada por meio do cache local do npm:
66
66
 
67
67
  ```bash
68
- npx --yes biaws-mcp@0.9.0
68
+ npx --yes biaws-mcp@0.10.0
69
69
  ```
70
70
 
71
71
  Também é possível instalá-lo explicitamente:
72
72
 
73
73
  ```bash
74
- npm install --global biaws-mcp@0.9.0
74
+ npm install --global biaws-mcp@0.10.0
75
75
  biaws-mcp
76
76
  ```
77
77
 
@@ -90,7 +90,7 @@ npm start
90
90
  Em um cliente MCP, configure o comando:
91
91
 
92
92
  ```bash
93
- npx --yes biaws-mcp@0.9.0
93
+ npx --yes biaws-mcp@0.10.0
94
94
  ```
95
95
 
96
96
  O fluxo recomendado é gerar a configuração completa com:
@@ -238,6 +238,36 @@ informa totais e truncamentos e não contém credenciais, endereços dos
238
238
  servidores, metadata dos runtimes, anexos nem os textos extensos da base de
239
239
  conhecimento.
240
240
 
241
+ ### Histórico de documentos
242
+
243
+ - `documents_list_revisions`: consulta até 100 revisões mais recentes.
244
+ - `documents_list_observations`: consulta até 200 observações mais recentes.
245
+
246
+ Ambas exigem `documentId` e preservam a autorização da API. Esses endpoints
247
+ não oferecem paginação.
248
+
249
+ ### Consultas de monitoramento
250
+
251
+ - `monitoring_runtime_topology_get`: consulta a topologia monitorada.
252
+ - `monitoring_runtime_targets_list`: lista os alvos de runtime monitorados.
253
+ - `monitoring_metadata_profiles_list`: lista os perfis de apresentação de
254
+ metadados; exige leitura de runtimes no escopo de workspace.
255
+ - `applications_monitoring_health_get`: consulta a saúde consolidada de uma
256
+ aplicação; `includeConfigured` inclui runtimes com monitores configurados
257
+ mesmo sem resultados recebidos (padrão `false`).
258
+ - `runtime_monitoring_signals_list`: lista sinais passivos/externos por runtime,
259
+ período e status, com `page` (padrão 1) e `limit` (padrão 50, máximo 100).
260
+ Para resultados de monitores ativos, use `runtime_monitoring_results_list`.
261
+
262
+ Topologia, alvos e perfis retornam o conjunto acessível fornecido pela API, sem
263
+ paginação. As consultas usam o workspace configurado no MCP.
264
+
265
+ ### Auditoria
266
+
267
+ - `audit_events_list`: consulta os eventos mais recentes de uma entidade, com
268
+ `entityType`, `entityId` e `limit` (padrão 100, máximo 200). Usa a permissão
269
+ de leitura e o escopo da entidade. A API não oferece paginação deste histórico.
270
+
241
271
  ### Issues / chamados
242
272
 
243
273
  - `issues_search`: busca issues com os mesmos filtros principais da
@@ -258,6 +288,8 @@ conhecimento.
258
288
  obrigatório.
259
289
  - `issues_import_eml`: analisa ou importa um EML enviado em Base64; `dryRun` é `true` por padrão.
260
290
  - `issues_update_state`: altera status e/ou tipo de uma issue.
291
+ - `issues_update`: altera título, texto, tipo, status, aplicação e componentes
292
+ afetados. Exige ao menos um campo e preserva os campos omitidos.
261
293
  - `issues_suggest_taxonomy`: sugere taxonomias aderentes ao texto da issue.
262
294
  - `issues_classify`: grava classificação/KB em `issues.classification`.
263
295
  - `issues_by_taxonomy`: busca issues por assunto/taxonomia, incluindo todos os
@@ -265,7 +297,11 @@ conhecimento.
265
297
 
266
298
  ### Melhorias
267
299
 
268
- - `demands_list`: lista melhorias com filtros simples e de contexto.
300
+ - `demands_list`: lista uma página de melhorias, com `page` (padrão 1),
301
+ `limit` (padrão 25, máximo 100), filtros de contexto e `collectionId`
302
+ (`__root__` seleciona a raiz). A resposta informa total, página e total de
303
+ páginas. Busca por `text` e código parcial em `code` percorre as páginas da
304
+ API e aplica os filtros antes da paginação do resultado.
269
305
  - `demands_get`: obtém uma melhoria estruturada.
270
306
  - `demands_create`: cria uma melhoria com dados cadastrais, especificação,
271
307
  checklist e planejamento; `applicationId` é obrigatório.
@@ -274,6 +310,19 @@ conhecimento.
274
310
  - `demands_implementation_context`: extrai contexto de especificação e tarefas para agentes de desenvolvimento.
275
311
  - `demands_add_note`: adiciona anotação a uma melhoria.
276
312
  - `demands_update_description`: atualiza a descrição sucinta da melhoria.
313
+ - `demands_update`: altera código, título, descrição, status, prazos, estimativa
314
+ de jornadas, aplicação e componentes afetados. Exige ao menos um campo;
315
+ campos omitidos são preservados pela API.
316
+ - `demands_update_specification`: substitui todas as seções da especificação.
317
+ - `demands_update_checklist`: substitui todos os itens do checklist, incluindo
318
+ conclusão, data e comentário.
319
+ - `demands_update_journeys`: substitui o planejamento mensal de jornadas.
320
+ Os meses devem estar dentro de `startDate`/`endDate` da melhoria; ajuste as
321
+ datas com `demands_update` primeiro. A API preenche meses do período não
322
+ informados com zero.
323
+ - `demands_update_note`: altera conteúdo e, opcionalmente, data de uma nota;
324
+ preserva a data existente quando omitida.
325
+ - `demands_delete_note`: exclui permanentemente uma nota da melhoria.
277
326
  - `demands_list_tasks`: lista tarefas, com filtro opcional por status.
278
327
  - `demands_create_task`: inclui uma tarefa.
279
328
  - `demands_update_task`: altera código, título, status, datas, situação, descrição ou especificação de uma tarefa.
@@ -283,6 +332,19 @@ conhecimento.
283
332
  - `demands_update_task_note`: altera uma nota de execução.
284
333
  - `demands_delete_task_note`: exclui uma nota de execução.
285
334
 
335
+ Calendário e prazos percorrem todas as páginas de melhorias no escopo informado,
336
+ com filtro opcional por `collectionId`. Essas consultas e a busca local de
337
+ `demands_list` leem até 100 páginas de 100 melhorias. Ao exceder o limite, retornam
338
+ `DEMAND_SCAN_LIMIT_EXCEEDED` e solicitam filtros mais específicos, sem devolver
339
+ um resultado parcial como completo.
340
+
341
+ As novas ferramentas de alteração aceitam `requestId` como ID ou código exato da melhoria.
342
+ Consulte `demands_get` antes de substituir especificação, checklist ou jornadas
343
+ para conservar os itens desejados. Arrays vazios limpam especificação e checklist;
344
+ para jornadas, zeram o planejamento no período da melhoria. IDs de seções,
345
+ rótulos de checklist e meses de jornadas devem ser únicos. As alterações usam
346
+ somente a API, com as mesmas permissões, escopo e auditoria da interface.
347
+
286
348
  ### Anexos
287
349
 
288
350
  - `attachments_upload`: envia até dez arquivos, fornecidos em
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "biaws-mcp",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Servidor MCP de domínio para o Bondia Workspaces",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -0,0 +1,10 @@
1
+ import { cleanParams, fetchJson } from "../../httpClient.js";
2
+
3
+ export async function listAuditEvents(args = {}) {
4
+ const entityId = String(args.entityId || "").trim();
5
+ if (!entityId) throw new Error("entityId is required");
6
+ return fetchJson(
7
+ `/api/audit/${encodeURIComponent(args.entityType)}/${encodeURIComponent(entityId)}`,
8
+ cleanParams({ limit: args.limit ?? 100 }),
9
+ );
10
+ }
@@ -0,0 +1,43 @@
1
+ import { listAuditEvents } from "./service.js";
2
+
3
+ export const auditTools = [
4
+ {
5
+ name: "audit_events_list",
6
+ description:
7
+ "Consulta os eventos mais recentes de auditoria de uma entidade, respeitando seu escopo e permissão de leitura. Retorna até 200 eventos; a API não oferece paginação deste histórico.",
8
+ inputSchema: {
9
+ type: "object",
10
+ required: ["entityType", "entityId"],
11
+ additionalProperties: false,
12
+ properties: {
13
+ entityType: {
14
+ type: "string",
15
+ enum: [
16
+ "issue",
17
+ "demand",
18
+ "task",
19
+ "document",
20
+ "taxonomy",
21
+ "skill",
22
+ "application",
23
+ "workspace",
24
+ "component",
25
+ "integration",
26
+ "repository",
27
+ "server",
28
+ "deployment",
29
+ "runtime",
30
+ ],
31
+ },
32
+ entityId: {
33
+ type: "string",
34
+ minLength: 1,
35
+ description:
36
+ "ID da entidade usado pela API; códigos de melhorias não são resolvidos nesta ferramenta.",
37
+ },
38
+ limit: { type: "integer", minimum: 1, maximum: 200, default: 100 },
39
+ },
40
+ },
41
+ handler: listAuditEvents,
42
+ },
43
+ ];
@@ -100,17 +100,44 @@ function compactDemand(request) {
100
100
  };
101
101
  }
102
102
 
103
- async function readAllDemands(args = {}) {
103
+ async function readDemandPage(args = {}, page = 1, limit = 25) {
104
104
  return fetchJson(
105
105
  "/api/requests",
106
106
  cleanParams({
107
107
  workspaceId: args.workspaceId,
108
108
  applicationId: args.applicationId,
109
109
  componentId: args.componentId,
110
+ collectionId: args.collectionId,
111
+ status: args.status,
112
+ page,
113
+ limit,
110
114
  }),
111
115
  );
112
116
  }
113
117
 
118
+ async function readAllDemands(args = {}) {
119
+ const items = [];
120
+ let meta = {};
121
+ // Bound traversal without returning an apparently complete partial result.
122
+ for (let page = 1; page <= 100; page += 1) {
123
+ const payload = await readDemandPage(args, page, 100);
124
+ items.push(...payload.items);
125
+ meta = payload.meta || {};
126
+ const totalPages = Number(
127
+ meta.totalPages ?? Math.ceil(Number(meta.total) / 100),
128
+ );
129
+ if (!Number.isFinite(totalPages) || page >= totalPages) {
130
+ return { meta, items };
131
+ }
132
+ }
133
+ const error = new Error(
134
+ "Demand scan exceeds 100 pages; narrow the application, component, status or collection filters",
135
+ );
136
+ error.code = "DEMAND_SCAN_LIMIT_EXCEEDED";
137
+ error.retryable = false;
138
+ throw error;
139
+ }
140
+
114
141
  async function readDemand(requestId) {
115
142
  const isObjectId = /^[0-9a-f]{24}$/iu.test(requestId);
116
143
  const payload = isObjectId
@@ -145,16 +172,31 @@ function journeySummaryForRequest(request) {
145
172
  }
146
173
 
147
174
  export async function listDemands(args = {}) {
148
- const payload = await readAllDemands(args);
175
+ const page = args.page ?? 1;
176
+ const limit = args.limit ?? 25;
177
+ // Text and partial-code matching remain MCP filters; filter before paging.
178
+ const locallyFiltered = Boolean(args.text || args.code);
179
+ const payload = locallyFiltered
180
+ ? await readAllDemands(args)
181
+ : await readDemandPage(args, page, limit);
149
182
  const filtered = filterDemands(payload.items, args);
150
-
183
+ const items = locallyFiltered
184
+ ? filtered.slice((page - 1) * limit, page * limit)
185
+ : filtered;
186
+ const total = locallyFiltered
187
+ ? filtered.length
188
+ : (payload.meta?.total ?? filtered.length);
151
189
  return {
152
190
  meta: {
153
191
  ...payload.meta,
154
- returned: filtered.length,
192
+ page,
193
+ limit,
194
+ total,
195
+ totalPages: Math.max(1, Math.ceil(total / limit)),
196
+ returned: items.length,
155
197
  filters: args,
156
198
  },
157
- items: args.includeDetails ? filtered : filtered.map(compactDemand),
199
+ items: args.includeDetails ? items : items.map(compactDemand),
158
200
  };
159
201
  }
160
202
 
@@ -479,12 +521,129 @@ export async function updateDemandDescription(args = {}) {
479
521
  if (!String(args.description || "").trim())
480
522
  throw new Error("description is required");
481
523
 
482
- const { request } = await readDemand(args.requestId);
524
+ return updateDemandFields(args, {
525
+ description: String(args.description).trim(),
526
+ });
527
+ }
528
+
529
+ function requiredText(value, field) {
530
+ const normalized = String(value || "").trim();
531
+ if (!normalized) throw new Error(`${field} is required`);
532
+ return normalized;
533
+ }
534
+
535
+ async function updateDemandFields(args, payload) {
536
+ const requestId = requiredText(args.requestId, "requestId");
537
+ const { request } = await readDemand(requestId);
538
+ if (payload.journeys) {
539
+ const from = String(request.startDate || "").slice(0, 7);
540
+ const to = String(request.endDate || "").slice(0, 7);
541
+ if (
542
+ payload.journeys.some(
543
+ (item) => !from || !to || item.month < from || item.month > to,
544
+ )
545
+ ) {
546
+ throw new Error(
547
+ "journeys.month must fall within the demand startDate/endDate; update its dates first",
548
+ );
549
+ }
550
+ }
551
+ // The API merges omitted fields and enforces field-specific permissions.
552
+ return sendJson(`/api/requests/${encodeURIComponent(request.id)}`, payload);
553
+ }
554
+
555
+ export async function updateDemand(args = {}) {
556
+ const fields = [
557
+ "clientCode",
558
+ "title",
559
+ "description",
560
+ "status",
561
+ "estimatedDeliveryDate",
562
+ "startDate",
563
+ "endDate",
564
+ "estimatedJourneys",
565
+ "applicationId",
566
+ "affectedComponentIds",
567
+ ];
568
+ const payload = {};
569
+ for (const field of fields) {
570
+ if (args[field] === undefined) continue;
571
+ payload[field] =
572
+ typeof args[field] === "string" ? args[field].trim() : args[field];
573
+ if (["title", "status", "applicationId"].includes(field)) {
574
+ payload[field] = requiredText(args[field], field);
575
+ }
576
+ }
577
+ if (!Object.keys(payload).length)
578
+ throw new Error("At least one update field is required");
579
+ if (payload.affectedComponentIds) {
580
+ payload.affectedComponentIds = payload.affectedComponentIds.map((id) =>
581
+ requiredText(id, "affectedComponentIds"),
582
+ );
583
+ assertUnique(payload.affectedComponentIds, "affectedComponentIds");
584
+ }
585
+ return updateDemandFields(args, payload);
586
+ }
587
+
588
+ function assertUnique(values, field) {
589
+ if (new Set(values).size !== values.length)
590
+ throw new Error(`${field} must be unique`);
591
+ }
592
+
593
+ export async function updateDemandSpecification(args = {}) {
594
+ const sections = args.specificationSections.map((section) => ({
595
+ ...section,
596
+ id: requiredText(section.id, "section.id"),
597
+ title: requiredText(section.title, "section.title"),
598
+ }));
599
+ assertUnique(
600
+ sections.map((section) => section.id),
601
+ "section.id",
602
+ );
603
+ return updateDemandFields(args, { specification: { sections } });
604
+ }
605
+
606
+ export async function updateDemandChecklist(args = {}) {
607
+ const checklist = args.checklist.map((item) => ({
608
+ ...item,
609
+ label: requiredText(item.label, "checklist.label"),
610
+ }));
611
+ assertUnique(
612
+ checklist.map((item) => item.label),
613
+ "checklist.label",
614
+ );
615
+ return updateDemandFields(args, { checklist });
616
+ }
617
+
618
+ export async function updateDemandJourneys(args = {}) {
619
+ assertUnique(
620
+ args.journeys.map((item) => item.month),
621
+ "journeys.month",
622
+ );
623
+ return updateDemandFields(args, { journeys: args.journeys });
624
+ }
625
+
626
+ async function readDemandNote(args) {
627
+ const requestId = requiredText(args.requestId, "requestId");
628
+ const noteId = requiredText(args.noteId, "noteId");
629
+ const { request } = await readDemand(requestId);
630
+ const note = (request.notes || []).find((item) => item.id === noteId);
631
+ if (!note) throw new Error(`Demand note not found: ${noteId}`);
632
+ return { request, note };
633
+ }
634
+
635
+ export async function updateDemandNote(args = {}) {
636
+ const content = requiredText(args.content, "content");
637
+ const { request, note } = await readDemandNote(args);
483
638
  return sendJson(
484
- `/api/requests/${encodeURIComponent(request.id)}`,
485
- cleanParams({
486
- ...request,
487
- description: String(args.description).trim(),
488
- }),
639
+ `/api/requests/${encodeURIComponent(request.id)}/notes/${encodeURIComponent(note.id)}`,
640
+ { content, date: args.date ?? note.date },
641
+ );
642
+ }
643
+
644
+ export async function deleteDemandNote(args = {}) {
645
+ const { request, note } = await readDemandNote(args);
646
+ return deleteJson(
647
+ `/api/requests/${encodeURIComponent(request.id)}/notes/${encodeURIComponent(note.id)}`,
489
648
  );
490
649
  }
@@ -0,0 +1,145 @@
1
+ import {
2
+ deleteDemandNote,
3
+ updateDemand,
4
+ updateDemandChecklist,
5
+ updateDemandJourneys,
6
+ updateDemandNote,
7
+ updateDemandSpecification,
8
+ } from "./service.js";
9
+
10
+ const requestId = {
11
+ type: "string",
12
+ minLength: 1,
13
+ description: "ID ou código exato da melhoria.",
14
+ };
15
+ const date = { type: "string", description: "YYYY-MM-DD ou vazio." };
16
+ const text = { type: "string", minLength: 1 };
17
+
18
+ function tool(name, description, properties, required, handler) {
19
+ return {
20
+ name,
21
+ description,
22
+ inputSchema: {
23
+ type: "object",
24
+ required: ["requestId", ...required],
25
+ additionalProperties: false,
26
+ properties: { requestId, ...properties },
27
+ },
28
+ handler,
29
+ };
30
+ }
31
+
32
+ export const demandMutationTools = [
33
+ tool(
34
+ "demands_update",
35
+ "Atualiza dados cadastrais, status, prazos e contexto de uma melhoria. Informe pelo menos um campo; campos omitidos são preservados.",
36
+ {
37
+ clientCode: { type: "string" },
38
+ title: text,
39
+ description: { type: "string" },
40
+ status: {
41
+ ...text,
42
+ description:
43
+ "Status vigente em Configurações/Listas de Opções; validado pela API.",
44
+ },
45
+ estimatedDeliveryDate: date,
46
+ startDate: date,
47
+ endDate: date,
48
+ estimatedJourneys: { type: "number", minimum: 0 },
49
+ applicationId: text,
50
+ affectedComponentIds: {
51
+ type: "array",
52
+ maxItems: 100,
53
+ uniqueItems: true,
54
+ items: text,
55
+ description:
56
+ "Substitui os componentes afetados; [] remove as associações.",
57
+ },
58
+ },
59
+ [],
60
+ updateDemand,
61
+ ),
62
+ tool(
63
+ "demands_update_specification",
64
+ "Substitui todas as seções da especificação de uma melhoria, preservando os demais dados. Consulte demands_get antes de editar; [] remove todas as seções.",
65
+ {
66
+ specificationSections: {
67
+ type: "array",
68
+ maxItems: 500,
69
+ items: {
70
+ type: "object",
71
+ required: ["id", "title", "content", "order"],
72
+ additionalProperties: false,
73
+ properties: {
74
+ id: text,
75
+ title: text,
76
+ content: { type: "string", description: "Conteúdo em Markdown." },
77
+ order: { type: "integer", minimum: 0 },
78
+ },
79
+ },
80
+ },
81
+ },
82
+ ["specificationSections"],
83
+ updateDemandSpecification,
84
+ ),
85
+ tool(
86
+ "demands_update_checklist",
87
+ "Substitui todos os itens do checklist de uma melhoria, incluindo conclusão, data e comentário. Consulte demands_get antes de editar; [] limpa o checklist.",
88
+ {
89
+ checklist: {
90
+ type: "array",
91
+ maxItems: 1000,
92
+ items: {
93
+ type: "object",
94
+ required: ["label", "done"],
95
+ additionalProperties: false,
96
+ properties: {
97
+ label: text,
98
+ done: { type: "boolean" },
99
+ date,
100
+ comment: { type: "string" },
101
+ },
102
+ },
103
+ },
104
+ },
105
+ ["checklist"],
106
+ updateDemandChecklist,
107
+ ),
108
+ tool(
109
+ "demands_update_journeys",
110
+ "Substitui o planejamento mensal de jornadas da melhoria. Consulte demands_get antes de editar; a API normaliza os meses segundo o período da melhoria.",
111
+ {
112
+ journeys: {
113
+ type: "array",
114
+ maxItems: 240,
115
+ items: {
116
+ type: "object",
117
+ required: ["month", "plannedJourneys"],
118
+ additionalProperties: false,
119
+ properties: {
120
+ month: { type: "string", pattern: "^\\d{4}-(0[1-9]|1[0-2])$" },
121
+ plannedJourneys: { type: "number", minimum: 0 },
122
+ executedJourneys: { type: "number", minimum: 0, default: 0 },
123
+ comment: { type: "string" },
124
+ },
125
+ },
126
+ },
127
+ },
128
+ ["journeys"],
129
+ updateDemandJourneys,
130
+ ),
131
+ tool(
132
+ "demands_update_note",
133
+ "Atualiza o conteúdo de uma nota da melhoria e, opcionalmente, sua data. A data existente é preservada quando omitida.",
134
+ { noteId: text, content: text, date },
135
+ ["noteId", "content"],
136
+ updateDemandNote,
137
+ ),
138
+ tool(
139
+ "demands_delete_note",
140
+ "Exclui permanentemente uma nota da melhoria identificada por noteId.",
141
+ { noteId: text },
142
+ ["noteId"],
143
+ deleteDemandNote,
144
+ ),
145
+ ];
@@ -405,3 +405,46 @@ export async function findIssuesByTaxonomy(args = {}) {
405
405
  }),
406
406
  );
407
407
  }
408
+
409
+ export async function updateIssue(args = {}) {
410
+ const issueId = String(args.issueId || "").trim();
411
+ if (!issueId) throw new Error("issueId is required");
412
+ const payload = {};
413
+ for (const field of [
414
+ "title",
415
+ "text",
416
+ "type",
417
+ "status",
418
+ "applicationId",
419
+ "affectedComponentIds",
420
+ ]) {
421
+ if (args[field] === undefined) continue;
422
+ const value =
423
+ typeof args[field] === "string" ? args[field].trim() : args[field];
424
+ if (typeof value === "string" && !value)
425
+ throw new Error(`${field} is required`);
426
+ payload[field] = value;
427
+ }
428
+ if (!Object.keys(payload).length)
429
+ throw new Error("At least one update field is required");
430
+ if (payload.affectedComponentIds) {
431
+ payload.affectedComponentIds = payload.affectedComponentIds.map((id) => {
432
+ const value = id.trim();
433
+ if (!value)
434
+ throw new Error("affectedComponentIds must contain nonblank IDs");
435
+ return value;
436
+ });
437
+ if (
438
+ new Set(payload.affectedComponentIds).size !==
439
+ payload.affectedComponentIds.length
440
+ ) {
441
+ throw new Error("affectedComponentIds must be unique");
442
+ }
443
+ }
444
+ return sendJson(
445
+ `/api/issues/${encodeURIComponent(issueId)}`,
446
+ payload,
447
+ {},
448
+ "PATCH",
449
+ );
450
+ }
@@ -136,3 +136,17 @@ export async function loadKnowledgeContext(args = {}) {
136
136
  documents,
137
137
  };
138
138
  }
139
+
140
+ function documentHistoryPath(args, suffix) {
141
+ const documentId = String(args.documentId || "").trim();
142
+ if (!documentId) throw new Error("documentId is required");
143
+ return `${BASE_PATH}/${encodeURIComponent(documentId)}/${suffix}`;
144
+ }
145
+
146
+ export async function listDocumentRevisions(args = {}) {
147
+ return fetchJson(documentHistoryPath(args, "revisions"));
148
+ }
149
+
150
+ export async function listDocumentObservations(args = {}) {
151
+ return fetchJson(documentHistoryPath(args, "observations"));
152
+ }
@@ -3,6 +3,8 @@ import {
3
3
  createDocument,
4
4
  getDocument,
5
5
  listDocumentTypes,
6
+ listDocumentRevisions,
7
+ listDocumentObservations,
6
8
  loadKnowledgeContext,
7
9
  searchDocuments,
8
10
  updateDocument,
@@ -319,6 +321,18 @@ export const knowledgeTools = [
319
321
  getDocument,
320
322
  schema({ documentId: ID }, ["documentId"]),
321
323
  ),
324
+ definition(
325
+ "documents_list_revisions",
326
+ "Consulta até 100 revisões mais recentes de um documento, em ordem decrescente de revisão. A API não oferece paginação deste histórico.",
327
+ listDocumentRevisions,
328
+ schema({ documentId: ID }, ["documentId"]),
329
+ ),
330
+ definition(
331
+ "documents_list_observations",
332
+ "Consulta até 200 observações mais recentes de um documento. A API não oferece paginação deste histórico.",
333
+ listDocumentObservations,
334
+ schema({ documentId: ID }, ["documentId"]),
335
+ ),
322
336
  definition(
323
337
  "documents_create",
324
338
  "Cria um documento usando o contrato discriminado pelo documentType. O workspace vem da configuração do MCP; applicationId e details seguem as regras de cada tipo.",
@@ -172,3 +172,37 @@ export function updateRuntimeActiveMonitor(args = {}) {
172
172
  export function archiveRuntimeActiveMonitor(args = {}) {
173
173
  return deleteJson(activeMonitorsPath(args, true));
174
174
  }
175
+
176
+ export async function getMonitoringRuntimeTopology() {
177
+ return fetchJson("/api/monitoring/runtime-topology");
178
+ }
179
+
180
+ export async function listMonitoringRuntimeTargets() {
181
+ return fetchJson("/api/monitoring/runtime-targets");
182
+ }
183
+
184
+ export async function listMonitoringMetadataProfiles() {
185
+ return fetchJson("/api/monitoring/metadata-profiles");
186
+ }
187
+
188
+ export async function getApplicationMonitoringHealth(args = {}) {
189
+ const applicationId = requiredId(args, "applicationId");
190
+ return fetchJson(
191
+ `/api/monitoring/applications/${segment(applicationId)}/health`,
192
+ cleanParams({ includeConfigured: args.includeConfigured ?? false }),
193
+ );
194
+ }
195
+
196
+ export async function listRuntimeMonitoringSignals(args = {}) {
197
+ const runtimeReference = requiredId(args, "runtimeReference");
198
+ return fetchJson(
199
+ `/api/monitoring/runtimes/${segment(runtimeReference)}/signals`,
200
+ cleanParams({
201
+ observedFrom: args.observedFrom,
202
+ observedTo: args.observedTo,
203
+ status: args.status,
204
+ page: args.page ?? 1,
205
+ limit: args.limit ?? 50,
206
+ }),
207
+ );
208
+ }
@@ -7,6 +7,11 @@ import {
7
7
  createRuntimeActiveMonitor,
8
8
  deactivateMonitoringTemplate,
9
9
  getMonitoringTemplate,
10
+ getMonitoringRuntimeTopology,
11
+ listMonitoringRuntimeTargets,
12
+ listMonitoringMetadataProfiles,
13
+ getApplicationMonitoringHealth,
14
+ listRuntimeMonitoringSignals,
10
15
  getMonitoringTemplateContract,
11
16
  getMonitoringTemplateUsage,
12
17
  getRuntimeMonitoringHealthSummary,
@@ -62,6 +67,63 @@ const TEMPLATE_VERSION_ID_SCHEMA = schema({ templateId: ID, version: ID }, [
62
67
  ]);
63
68
 
64
69
  export const monitoringTools = [
70
+ definition(
71
+ "monitoring_runtime_topology_get",
72
+ "Consulta a topologia monitorada no escopo autorizado. A API retorna a árvore completa acessível sem paginação.",
73
+ getMonitoringRuntimeTopology,
74
+ schema(),
75
+ ),
76
+ definition(
77
+ "monitoring_runtime_targets_list",
78
+ "Lista os alvos de runtime monitorados no escopo autorizado. A API retorna todos os alvos acessíveis sem paginação.",
79
+ listMonitoringRuntimeTargets,
80
+ schema(),
81
+ ),
82
+ definition(
83
+ "monitoring_metadata_profiles_list",
84
+ "Lista os perfis de apresentação de metadados do workspace; exige permissão de leitura de runtimes no escopo de workspace. A API não oferece paginação.",
85
+ listMonitoringMetadataProfiles,
86
+ schema(),
87
+ ),
88
+ definition(
89
+ "applications_monitoring_health_get",
90
+ "Consulta a saúde consolidada e os detalhes de monitoramento de uma aplicação. includeConfigured inclui runtimes com monitores configurados mesmo sem resultados recebidos.",
91
+ getApplicationMonitoringHealth,
92
+ schema(
93
+ {
94
+ applicationId: ID,
95
+ includeConfigured: { type: "boolean", default: false },
96
+ },
97
+ ["applicationId"],
98
+ ),
99
+ ),
100
+ definition(
101
+ "runtime_monitoring_signals_list",
102
+ "Lista uma página de sinais passivos ou externos de um runtime, filtrados por período e status. Para incluir resultados de monitores ativos, use runtime_monitoring_results_list.",
103
+ listRuntimeMonitoringSignals,
104
+ schema(
105
+ {
106
+ runtimeReference: ID,
107
+ observedFrom: {
108
+ type: "string",
109
+ description:
110
+ "Data YYYY-MM-DD ou instante ISO 8601 inicial, inclusivo.",
111
+ },
112
+ observedTo: {
113
+ type: "string",
114
+ description:
115
+ "Data YYYY-MM-DD incluindo o dia inteiro ou instante ISO 8601 final, inclusivo.",
116
+ },
117
+ status: {
118
+ type: "string",
119
+ enum: ["unknown", "healthy", "degraded", "unavailable", "stopped"],
120
+ },
121
+ page: { type: "integer", minimum: 1, default: 1 },
122
+ limit: { type: "integer", minimum: 1, maximum: 100, default: 50 },
123
+ },
124
+ ["runtimeReference"],
125
+ ),
126
+ ),
65
127
  definition(
66
128
  "monitoring_templates_list",
67
129
  "Lista templates de monitoramento versionados do workspace configurado, com filtro de status e paginação.",
package/src/tools.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  summarizeIssuesForSupport,
12
12
  suggestTaxonomy,
13
13
  updateIssueState,
14
+ updateIssue,
14
15
  updateIssueComment,
15
16
  updateTaxonomyItem,
16
17
  } from "./domains/issues/service.js";
@@ -36,6 +37,8 @@ import { catalogTools } from "./domains/catalog/tools.js";
36
37
  import { collectionTools } from "./domains/collections/tools.js";
37
38
  import { secretTools } from "./domains/secrets/tools.js";
38
39
  import { knowledgeTools } from "./domains/knowledge/tools.js";
40
+ import { auditTools } from "./domains/audit/tools.js";
41
+ import { demandMutationTools } from "./domains/demands/tools.js";
39
42
  import { attachmentTools } from "./domains/attachments/tools.js";
40
43
  import { monitoringTools } from "./domains/monitoring/tools.js";
41
44
 
@@ -140,6 +143,8 @@ const tools = [
140
143
  ...secretTools,
141
144
  ...knowledgeTools,
142
145
  ...attachmentTools,
146
+ ...demandMutationTools,
147
+ ...auditTools,
143
148
  ...monitoringTools,
144
149
  {
145
150
  name: "issues_search",
@@ -165,6 +170,35 @@ const tools = [
165
170
  },
166
171
  handler: getIssueDetails,
167
172
  },
173
+ {
174
+ name: "issues_update",
175
+ description:
176
+ "Atualiza título, texto, tipo, status, aplicação e componentes afetados de uma issue. Informe ao menos um campo; campos omitidos são preservados pela API.",
177
+ inputSchema: {
178
+ type: "object",
179
+ required: ["issueId"],
180
+ additionalProperties: false,
181
+ properties: {
182
+ issueId: { type: "string", minLength: 1 },
183
+ title: { type: "string", minLength: 1 },
184
+ text: {
185
+ type: "string",
186
+ minLength: 1,
187
+ description: "Conteúdo em Markdown.",
188
+ },
189
+ type: { type: "string", enum: ["incident", "request"] },
190
+ status: { type: "string", enum: ["open", "closed"] },
191
+ applicationId: { type: "string", minLength: 1 },
192
+ affectedComponentIds: {
193
+ type: "array",
194
+ maxItems: 100,
195
+ uniqueItems: true,
196
+ items: { type: "string", minLength: 1 },
197
+ },
198
+ },
199
+ },
200
+ handler: updateIssue,
201
+ },
168
202
  {
169
203
  name: "issues_add_comment",
170
204
  description: "Adiciona um comentário em Markdown a uma issue existente.",
@@ -482,7 +516,7 @@ const tools = [
482
516
  {
483
517
  name: "demands_list",
484
518
  description:
485
- "Lista melhorias com filtros simples por status, texto e código.",
519
+ "Lista uma página de melhorias por status, texto, código e coleção. Texto e código parcial são filtrados antes da paginação; consultas com esses filtros percorrem até 100 páginas da API.",
486
520
  inputSchema: {
487
521
  type: "object",
488
522
  additionalProperties: false,
@@ -491,6 +525,12 @@ const tools = [
491
525
  text: { type: "string" },
492
526
  code: { type: "string" },
493
527
  includeDetails: { type: "boolean", default: false },
528
+ page: { type: "integer", minimum: 1, default: 1 },
529
+ limit: { type: "integer", minimum: 1, maximum: 100, default: 25 },
530
+ collectionId: {
531
+ type: "string",
532
+ description: "ID da coleção; __root__ filtra melhorias na raiz.",
533
+ },
494
534
  ...KNOWLEDGE_CONTEXT_FILTER_PROPERTIES,
495
535
  },
496
536
  },
@@ -604,6 +644,10 @@ const tools = [
604
644
  fromMonth: { type: "string", description: "YYYY-MM" },
605
645
  toMonth: { type: "string", description: "YYYY-MM" },
606
646
  status: { type: "string" },
647
+ collectionId: {
648
+ type: "string",
649
+ description: "ID da coleção ou __root__.",
650
+ },
607
651
  ...KNOWLEDGE_CONTEXT_FILTER_PROPERTIES,
608
652
  },
609
653
  },
@@ -622,6 +666,10 @@ const tools = [
622
666
  type: "string",
623
667
  description: "YYYY-MM-DD. Default: hoje.",
624
668
  },
669
+ collectionId: {
670
+ type: "string",
671
+ description: "ID da coleção ou __root__.",
672
+ },
625
673
  ...KNOWLEDGE_CONTEXT_FILTER_PROPERTIES,
626
674
  },
627
675
  },
package/src/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export const SERVER_NAME = "biaws-mcp";
2
- export const SERVER_VERSION = "0.9.0";
2
+ export const SERVER_VERSION = "0.10.0";