glpi-mcp-server 1.0.0 → 1.0.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.
Files changed (2) hide show
  1. package/index.js +59 -19
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -2,28 +2,68 @@
2
2
 
3
3
  const readline = require('readline');
4
4
 
5
- // Lê argumentos da linha de comando ou variáveis de ambiente
5
+ // Lê argumentos da linha de comando
6
6
  const args = process.argv.slice(2);
7
- let url = process.env.GLPI_URL || '';
8
- let token = process.env.GLPI_TOKEN || '';
7
+ const config = {
8
+ glpiUrl: process.env.GLPI_URL || '',
9
+ clientId: process.env.GLPI_CLIENT_ID || '',
10
+ clientSecret: process.env.GLPI_CLIENT_SECRET || '',
11
+ username: process.env.GLPI_USERNAME || '',
12
+ password: process.env.GLPI_PASSWORD || ''
13
+ };
9
14
 
10
15
  for (let i = 0; i < args.length; i++) {
11
- if (args[i] === '--url' && args[i + 1]) {
12
- url = args[i + 1];
13
- i++;
14
- } else if (args[i] === '--token' && args[i + 1]) {
15
- token = args[i + 1];
16
- i++;
17
- }
16
+ if (args[i] === '--glpi-url' && args[i + 1]) { config.glpiUrl = args[i + 1]; i++; }
17
+ else if (args[i] === '--client-id' && args[i + 1]) { config.clientId = args[i + 1]; i++; }
18
+ else if (args[i] === '--client-secret' && args[i + 1]) { config.clientSecret = args[i + 1]; i++; }
19
+ else if (args[i] === '--username' && args[i + 1]) { config.username = args[i + 1]; i++; }
20
+ else if (args[i] === '--password' && args[i + 1]) { config.password = args[i + 1]; i++; }
18
21
  }
19
22
 
20
- if (!url || !token) {
21
- console.error("Uso: npx glpi-mcp-server --url <URL_DO_PLUGIN> --token <JWT_TOKEN>");
22
- console.error("Ou use variáveis de ambiente GLPI_URL e GLPI_TOKEN.");
23
+ if (!config.glpiUrl || !config.clientId || !config.clientSecret || !config.username || !config.password) {
24
+ console.error("Uso: npx glpi-mcp-server --glpi-url <URL> --client-id <ID> --client-secret <SECRET> --username <USER> --password <PASS>");
23
25
  process.exit(1);
24
26
  }
25
27
 
26
- // Inicia a leitura do stdio (onde a IA envia as mensagens JSON-RPC)
28
+ // Remove trailing slash if present
29
+ config.glpiUrl = config.glpiUrl.replace(/\/$/, '');
30
+
31
+ let activeToken = null;
32
+
33
+ // Função para obter ou renovar o token
34
+ async function getValidToken() {
35
+ if (activeToken) return activeToken; // Idealmente, implementar renovação com expiração, mas mantemos simples por ora
36
+
37
+ const tokenUrl = `${config.glpiUrl}/api.php/token`;
38
+ const body = new URLSearchParams({
39
+ grant_type: 'password',
40
+ username: config.username,
41
+ password: config.password,
42
+ client_id: config.clientId,
43
+ client_secret: config.clientSecret,
44
+ scope: 'api'
45
+ });
46
+
47
+ const response = await fetch(tokenUrl, {
48
+ method: 'POST',
49
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
50
+ body: body.toString()
51
+ });
52
+
53
+ if (!response.ok) {
54
+ throw new Error(`Falha na autenticação OAuth. Status: ${response.status}`);
55
+ }
56
+
57
+ const data = await response.json();
58
+ if (!data.access_token) {
59
+ throw new Error("Token não retornado pela API");
60
+ }
61
+
62
+ activeToken = data.access_token;
63
+ return activeToken;
64
+ }
65
+
66
+ // Inicia a leitura do stdio
27
67
  const rl = readline.createInterface({
28
68
  input: process.stdin,
29
69
  output: process.stdout,
@@ -34,7 +74,10 @@ rl.on('line', async (line) => {
34
74
  if (!line.trim()) return;
35
75
 
36
76
  try {
37
- const response = await fetch(url, {
77
+ const token = await getValidToken();
78
+ const mcpUrl = `${config.glpiUrl}/plugins/mcprotocol/ajax/mcp.php`;
79
+
80
+ const response = await fetch(mcpUrl, {
38
81
  method: 'POST',
39
82
  headers: {
40
83
  'Content-Type': 'application/json',
@@ -44,19 +87,16 @@ rl.on('line', async (line) => {
44
87
  });
45
88
 
46
89
  const data = await response.text();
47
- // Repassa a resposta de volta para a IA via stdout
48
90
  process.stdout.write(data + "\n");
49
91
 
50
92
  } catch (error) {
51
- // Em caso de erro de rede, tenta enviar uma resposta de erro no formato JSON-RPC
52
93
  const errorMsg = JSON.stringify({
53
94
  jsonrpc: "2.0",
54
- error: { code: -32000, message: `MCP Proxy Network Error: ${error.message}` },
95
+ error: { code: -32000, message: `MCP Proxy Error: ${error.message}` },
55
96
  id: null
56
97
  });
57
98
  process.stdout.write(errorMsg + "\n");
58
99
  }
59
100
  });
60
101
 
61
- // Mantém o processo vivo esperando entradas
62
102
  process.stdin.resume();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glpi-mcp-server",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Model Context Protocol (MCP) server proxy for GLPI 11 REST API",
5
5
  "main": "index.js",
6
6
  "bin": {