innov-mcp-tasks 1.5.0 → 1.6.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 +8 -0
- package/index.mjs +105 -0
- package/lib/serverMonitoring.mjs +98 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -82,6 +82,14 @@ Na raiz do repo existe [`.cursor/mcp.json`](../.cursor/mcp.json) com **dois** se
|
|
|
82
82
|
- `agents_list` — agentes utilizáveis pelo token (`GET /api/v1/ai-agents?scope=usable`); opcional `scope=manageable` para gestão
|
|
83
83
|
- `agent_chat` — envia `message` a um agente (`POST /api/v1/ai-agents/{ulid}/chat`); devolve `response` e `citations`; opcional `conversation_ulid`, `project_id`, `notebook_id`
|
|
84
84
|
|
|
85
|
+
### Infraestrutura / servidores (SPEC-022)
|
|
86
|
+
|
|
87
|
+
- `servers_dashboard` — resumo online/offline, alertas e aplicações (`GET /server-monitoring/dashboard`)
|
|
88
|
+
- `servers_list` — lista servidores com métricas; filtros opcionais `status`, `search`
|
|
89
|
+
- `server_get` — detalhe por `server_ulid` (métricas + aplicações com tipo/versão)
|
|
90
|
+
- `server_alerts` — alertas ativos de CPU, RAM, disco e aplicações
|
|
91
|
+
- `server_applications_search` — busca apps (`search`, `type`, `server_ulid`, `env_production`, `debug_enabled`, paginação)
|
|
92
|
+
|
|
85
93
|
## Publicar no npm (mantenedor)
|
|
86
94
|
|
|
87
95
|
1. Define o **nome** em `package.json` (`innov-mcp-tasks` ou `@scope/innov-mcp-tasks` se o nome simples estiver tomado).
|
package/index.mjs
CHANGED
|
@@ -7,6 +7,13 @@ import { z } from 'zod';
|
|
|
7
7
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
8
8
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
9
9
|
import { agentChat, agentsList } from './lib/agents.mjs';
|
|
10
|
+
import {
|
|
11
|
+
serverAlerts,
|
|
12
|
+
serverApplicationsSearch,
|
|
13
|
+
serverGet,
|
|
14
|
+
serversDashboard,
|
|
15
|
+
serversList,
|
|
16
|
+
} from './lib/serverMonitoring.mjs';
|
|
10
17
|
|
|
11
18
|
const base = (process.env.INNOV_API_BASE_URL || '').replace(/\/$/, '');
|
|
12
19
|
const token = (process.env.INNOV_API_TOKEN || '').trim();
|
|
@@ -862,5 +869,103 @@ server.registerTool(
|
|
|
862
869
|
},
|
|
863
870
|
);
|
|
864
871
|
|
|
872
|
+
server.registerTool(
|
|
873
|
+
'servers_dashboard',
|
|
874
|
+
{
|
|
875
|
+
description:
|
|
876
|
+
'Resumo do monitoramento de servidores (GET /server-monitoring/dashboard): online/offline, alertas e aplicações.',
|
|
877
|
+
inputSchema: {},
|
|
878
|
+
},
|
|
879
|
+
async () => {
|
|
880
|
+
try {
|
|
881
|
+
const data = await serversDashboard(apiFetch);
|
|
882
|
+
return jsonText(data);
|
|
883
|
+
} catch (e) {
|
|
884
|
+
return jsonError(e instanceof Error ? e.message : String(e));
|
|
885
|
+
}
|
|
886
|
+
},
|
|
887
|
+
);
|
|
888
|
+
|
|
889
|
+
server.registerTool(
|
|
890
|
+
'servers_list',
|
|
891
|
+
{
|
|
892
|
+
description:
|
|
893
|
+
'Lista servidores monitorados com métricas recentes (GET /server-monitoring/servers).',
|
|
894
|
+
inputSchema: {
|
|
895
|
+
status: z.enum(['active', 'inactive']).optional(),
|
|
896
|
+
search: z.string().optional().describe('Hostname, IP ou descrição'),
|
|
897
|
+
},
|
|
898
|
+
},
|
|
899
|
+
async (args) => {
|
|
900
|
+
try {
|
|
901
|
+
const data = await serversList(apiFetch, args);
|
|
902
|
+
return jsonText(data);
|
|
903
|
+
} catch (e) {
|
|
904
|
+
return jsonError(e instanceof Error ? e.message : String(e));
|
|
905
|
+
}
|
|
906
|
+
},
|
|
907
|
+
);
|
|
908
|
+
|
|
909
|
+
server.registerTool(
|
|
910
|
+
'server_get',
|
|
911
|
+
{
|
|
912
|
+
description:
|
|
913
|
+
'Detalhe de um servidor: métricas, histórico e aplicações detectadas (GET /server-monitoring/servers/{ulid}).',
|
|
914
|
+
inputSchema: {
|
|
915
|
+
server_ulid: z.string().min(1).describe('ULID do servidor'),
|
|
916
|
+
},
|
|
917
|
+
},
|
|
918
|
+
async (args) => {
|
|
919
|
+
try {
|
|
920
|
+
const data = await serverGet(apiFetch, args);
|
|
921
|
+
return jsonText(data);
|
|
922
|
+
} catch (e) {
|
|
923
|
+
return jsonError(e instanceof Error ? e.message : String(e));
|
|
924
|
+
}
|
|
925
|
+
},
|
|
926
|
+
);
|
|
927
|
+
|
|
928
|
+
server.registerTool(
|
|
929
|
+
'server_alerts',
|
|
930
|
+
{
|
|
931
|
+
description:
|
|
932
|
+
'Alertas ativos de infraestrutura: CPU, RAM, disco e aplicações (GET /server-monitoring/alerts).',
|
|
933
|
+
inputSchema: {},
|
|
934
|
+
},
|
|
935
|
+
async () => {
|
|
936
|
+
try {
|
|
937
|
+
const data = await serverAlerts(apiFetch);
|
|
938
|
+
return jsonText(data);
|
|
939
|
+
} catch (e) {
|
|
940
|
+
return jsonError(e instanceof Error ? e.message : String(e));
|
|
941
|
+
}
|
|
942
|
+
},
|
|
943
|
+
);
|
|
944
|
+
|
|
945
|
+
server.registerTool(
|
|
946
|
+
'server_applications_search',
|
|
947
|
+
{
|
|
948
|
+
description:
|
|
949
|
+
'Busca aplicações nos servidores: stack (laravel, vuejs…), versão, ambiente (GET /server-monitoring/applications/search).',
|
|
950
|
+
inputSchema: {
|
|
951
|
+
search: z.string().optional(),
|
|
952
|
+
type: z.string().optional().describe('laravel, vuejs, symfony, wordpress, etc.'),
|
|
953
|
+
server_ulid: z.string().optional(),
|
|
954
|
+
env_production: z.boolean().optional(),
|
|
955
|
+
debug_enabled: z.boolean().optional(),
|
|
956
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
957
|
+
page: z.number().int().min(1).optional(),
|
|
958
|
+
},
|
|
959
|
+
},
|
|
960
|
+
async (args) => {
|
|
961
|
+
try {
|
|
962
|
+
const data = await serverApplicationsSearch(apiFetch, args);
|
|
963
|
+
return jsonText(data);
|
|
964
|
+
} catch (e) {
|
|
965
|
+
return jsonError(e instanceof Error ? e.message : String(e));
|
|
966
|
+
}
|
|
967
|
+
},
|
|
968
|
+
);
|
|
969
|
+
|
|
865
970
|
const transport = new StdioServerTransport();
|
|
866
971
|
await server.connect(transport);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/** Helpers e handlers para ferramentas de monitoramento de servidores (SPEC-022). */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {Record<string, string | number | boolean | undefined | null>} [params]
|
|
5
|
+
*/
|
|
6
|
+
export function serverMonitoringQueryString(params = {}) {
|
|
7
|
+
const search = new URLSearchParams();
|
|
8
|
+
for (const [key, value] of Object.entries(params)) {
|
|
9
|
+
if (value === undefined || value === null || value === '') {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
search.set(key, String(value));
|
|
13
|
+
}
|
|
14
|
+
const qs = search.toString();
|
|
15
|
+
return qs ? `?${qs}` : '';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function serversDashboardPath() {
|
|
19
|
+
return '/api/v1/server-monitoring/dashboard';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {{ status?: string, search?: string }} [args]
|
|
24
|
+
*/
|
|
25
|
+
export function serversListPath(args = {}) {
|
|
26
|
+
return `/api/v1/server-monitoring/servers${serverMonitoringQueryString({
|
|
27
|
+
status: args.status,
|
|
28
|
+
search: args.search,
|
|
29
|
+
})}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {string} serverUlid
|
|
34
|
+
*/
|
|
35
|
+
export function serverGetPath(serverUlid) {
|
|
36
|
+
const trimmed = String(serverUlid ?? '').trim();
|
|
37
|
+
if (!trimmed) {
|
|
38
|
+
throw new Error('server_ulid é obrigatório');
|
|
39
|
+
}
|
|
40
|
+
return `/api/v1/server-monitoring/servers/${encodeURIComponent(trimmed)}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function serverAlertsPath() {
|
|
44
|
+
return '/api/v1/server-monitoring/alerts';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {Record<string, string | number | boolean | undefined | null>} [args]
|
|
49
|
+
*/
|
|
50
|
+
export function serverApplicationsSearchPath(args = {}) {
|
|
51
|
+
const { limit, page, ...rest } = args;
|
|
52
|
+
return `/api/v1/server-monitoring/applications/search${serverMonitoringQueryString({
|
|
53
|
+
...rest,
|
|
54
|
+
per_page: limit ?? rest.per_page,
|
|
55
|
+
page,
|
|
56
|
+
})}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param {(path: string, init?: RequestInit) => Promise<unknown>} apiFetch
|
|
61
|
+
*/
|
|
62
|
+
export async function serversDashboard(apiFetch) {
|
|
63
|
+
return apiFetch(serversDashboardPath());
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {(path: string, init?: RequestInit) => Promise<unknown>} apiFetch
|
|
68
|
+
* @param {{ status?: string, search?: string }} [args]
|
|
69
|
+
*/
|
|
70
|
+
export async function serversList(apiFetch, args = {}) {
|
|
71
|
+
const data = await apiFetch(serversListPath(args));
|
|
72
|
+
return data?.data ?? data;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {(path: string, init?: RequestInit) => Promise<unknown>} apiFetch
|
|
77
|
+
* @param {{ server_ulid: string }} args
|
|
78
|
+
*/
|
|
79
|
+
export async function serverGet(apiFetch, args) {
|
|
80
|
+
const data = await apiFetch(serverGetPath(args.server_ulid));
|
|
81
|
+
return data?.data ?? data;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param {(path: string, init?: RequestInit) => Promise<unknown>} apiFetch
|
|
86
|
+
*/
|
|
87
|
+
export async function serverAlerts(apiFetch) {
|
|
88
|
+
const data = await apiFetch(serverAlertsPath());
|
|
89
|
+
return data?.data ?? data;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param {(path: string, init?: RequestInit) => Promise<unknown>} apiFetch
|
|
94
|
+
* @param {Record<string, string | number | boolean | undefined | null>} [args]
|
|
95
|
+
*/
|
|
96
|
+
export async function serverApplicationsSearch(apiFetch, args = {}) {
|
|
97
|
+
return apiFetch(serverApplicationsSearchPath(args));
|
|
98
|
+
}
|