@letoribo/mcpgql 1.1.0 → 1.2.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/core.ts +55 -24
- package/package.json +1 -1
package/core.ts
CHANGED
|
@@ -5,23 +5,31 @@ import { stdin as input, stdout as output } from 'process';
|
|
|
5
5
|
import * as path from 'path';
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
|
|
8
|
-
// --- Interfaces ---
|
|
9
8
|
interface Config {
|
|
10
9
|
activeEndpoints: string[];
|
|
11
10
|
endpoints: Record<string, string>;
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
// --- Initialization ---
|
|
15
13
|
const rl = readline.createInterface({ input, output });
|
|
16
|
-
|
|
17
14
|
const configPath = path.join(process.cwd(), 'mcpgql.config.json');
|
|
15
|
+
const headersPath = path.join(process.cwd(), 'headers.json');
|
|
16
|
+
|
|
17
|
+
// Initialize the file with an empty object if it does not exist
|
|
18
|
+
if (!fs.existsSync(headersPath)) {
|
|
19
|
+
fs.writeFileSync(headersPath, JSON.stringify({}, null, 2));
|
|
20
|
+
}
|
|
21
|
+
|
|
18
22
|
const config: Config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
19
23
|
const entries: [string, string][] = Object.entries(config.endpoints);
|
|
20
24
|
|
|
21
|
-
// Default: first endpoint is selected
|
|
22
25
|
const selected = new Set<string>();
|
|
23
26
|
if (entries.length > 0) selected.add(entries[0][0]);
|
|
24
27
|
|
|
28
|
+
let allowMutations = false;
|
|
29
|
+
|
|
30
|
+
// Load headers
|
|
31
|
+
let headers = fs.readFileSync(headersPath, 'utf-8');
|
|
32
|
+
|
|
25
33
|
function getDistPath(): string {
|
|
26
34
|
let current = process.cwd();
|
|
27
35
|
while (true) {
|
|
@@ -31,14 +39,13 @@ function getDistPath(): string {
|
|
|
31
39
|
if (parent === current) break;
|
|
32
40
|
current = parent;
|
|
33
41
|
}
|
|
34
|
-
return path.join(
|
|
35
|
-
path.dirname(require.resolve('@letoribo/mcp-graphql-enhanced/package.json')),
|
|
36
|
-
'dist/index.js'
|
|
37
|
-
);
|
|
42
|
+
return path.join(path.dirname(require.resolve('@letoribo/mcp-graphql-enhanced/package.json')), 'dist/index.js');
|
|
38
43
|
}
|
|
39
44
|
|
|
40
|
-
// --- Core Logic ---
|
|
41
45
|
async function startSelection() {
|
|
46
|
+
const mutationIdx = entries.length + 1;
|
|
47
|
+
const headersIdx = entries.length + 2;
|
|
48
|
+
|
|
42
49
|
while (true) {
|
|
43
50
|
console.clear();
|
|
44
51
|
console.log('\n--- Select Endpoints (Enter to confirm) ---');
|
|
@@ -46,24 +53,51 @@ async function startSelection() {
|
|
|
46
53
|
console.log(`${selected.has(key) ? ' [✓] ' : ' [ ] '} ${i + 1}. ${key}`);
|
|
47
54
|
});
|
|
48
55
|
|
|
49
|
-
|
|
56
|
+
console.log('--- Environment variables ---');
|
|
57
|
+
const mutationStatus = allowMutations ? '[YES]' : '[NO]';
|
|
58
|
+
console.log(`${mutationStatus} ${mutationIdx}. Allow Mutations`);
|
|
50
59
|
|
|
60
|
+
let hasAuth = false;
|
|
61
|
+
try { if (Object.keys(JSON.parse(headers)).length > 0) hasAuth = true; } catch (e) {}
|
|
62
|
+
console.log(`${hasAuth ? '[OK]' : '[ ]'} ${headersIdx}. Headers (Loaded from: ${headersPath})`);
|
|
63
|
+
|
|
64
|
+
const choice = await rl.question('\nEnter number to toggle (or Enter to proceed): ');
|
|
51
65
|
if (choice.trim() === '') break;
|
|
52
66
|
|
|
53
|
-
const
|
|
67
|
+
const choiceNum = parseInt(choice.trim());
|
|
68
|
+
const idx = choiceNum - 1;
|
|
69
|
+
|
|
54
70
|
if (idx >= 0 && idx < entries.length) {
|
|
55
71
|
const key = entries[idx][0];
|
|
56
72
|
selected.has(key) ? selected.delete(key) : selected.add(key);
|
|
73
|
+
} else if (choiceNum === mutationIdx) {
|
|
74
|
+
allowMutations = !allowMutations;
|
|
75
|
+
} else if (choiceNum === headersIdx) {
|
|
76
|
+
console.log('\n--- Paste JSON for headers.json ---');
|
|
77
|
+
console.log('Current: ' + headers);
|
|
78
|
+
const input = await rl.question('Paste new JSON (e.g. {"Authorization": "..."}): ');
|
|
79
|
+
|
|
80
|
+
if (input.trim() !== '') {
|
|
81
|
+
try {
|
|
82
|
+
const parsed = JSON.parse(input);
|
|
83
|
+
fs.writeFileSync(headersPath, JSON.stringify(parsed, null, 2));
|
|
84
|
+
headers = JSON.stringify(parsed);
|
|
85
|
+
console.log('[INFO] headers.json successfully updated.');
|
|
86
|
+
} catch (e) {
|
|
87
|
+
console.log('[ERROR] Invalid JSON! Update aborted.');
|
|
88
|
+
}
|
|
89
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
90
|
+
}
|
|
57
91
|
}
|
|
58
92
|
}
|
|
59
93
|
}
|
|
60
94
|
|
|
61
95
|
async function main() {
|
|
62
96
|
await startSelection();
|
|
63
|
-
|
|
97
|
+
|
|
64
98
|
const selectedUrls = Array.from(selected).map(k => config.endpoints[k]);
|
|
65
99
|
if (selectedUrls.length === 0) {
|
|
66
|
-
console.log('[ERROR] No endpoints selected.');
|
|
100
|
+
console.log('[ERROR] No endpoints selected. Exiting.');
|
|
67
101
|
rl.close();
|
|
68
102
|
process.exit(1);
|
|
69
103
|
}
|
|
@@ -72,31 +106,28 @@ async function main() {
|
|
|
72
106
|
console.log('2. MCP Inspector (stdio)');
|
|
73
107
|
const mode = await rl.question('Select mode (1 or 2): ');
|
|
74
108
|
|
|
75
|
-
// Environment setup
|
|
76
|
-
const endpointString = selectedUrls.join(',');
|
|
77
109
|
const spawnEnv: Record<string, string> = {
|
|
78
110
|
...(process.env as Record<string, string>),
|
|
79
|
-
ENDPOINT:
|
|
111
|
+
ENDPOINT: selectedUrls.join(','),
|
|
112
|
+
ALLOW_MUTATIONS: String(allowMutations),
|
|
113
|
+
HEADERS: headers
|
|
80
114
|
};
|
|
81
115
|
|
|
116
|
+
console.log(`[INFO] Launching with ENDPOINT=${spawnEnv.ENDPOINT}`);
|
|
82
117
|
rl.close();
|
|
83
118
|
|
|
84
119
|
const distPath = getDistPath();
|
|
120
|
+
console.log(`[DEBUG] Executing: node ${distPath}`);
|
|
121
|
+
|
|
85
122
|
if (mode === '1') {
|
|
86
123
|
spawnEnv['ENABLE_HTTP'] = 'true';
|
|
87
|
-
|
|
88
|
-
spawn('node', [distPath], { stdio: 'inherit', cwd: process.cwd(), env: spawnEnv });
|
|
124
|
+
spawn('node', [distPath], { stdio: 'inherit', env: spawnEnv });
|
|
89
125
|
} else {
|
|
90
|
-
console.log('Launching in Inspector mode...');
|
|
91
126
|
spawn('npx', ['-y', '@modelcontextprotocol/inspector', 'node', distPath], {
|
|
92
127
|
stdio: 'inherit',
|
|
93
|
-
cwd: process.cwd(),
|
|
94
128
|
env: spawnEnv
|
|
95
129
|
});
|
|
96
130
|
}
|
|
97
131
|
}
|
|
98
132
|
|
|
99
|
-
main().catch(err => {
|
|
100
|
-
console.error(err);
|
|
101
|
-
process.exit(1);
|
|
102
|
-
});
|
|
133
|
+
main().catch(err => { console.error(err); process.exit(1); });
|