@letoribo/mcp-graphql-enhanced 3.0.1 → 3.1.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/dist/helpers/introspection.d.ts.map +1 -1
- package/dist/helpers/introspection.js +14 -10
- package/dist/index.js +15 -57
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"introspection.d.ts","sourceRoot":"","sources":["../../src/helpers/introspection.ts"],"names":[],"mappings":"AAcA;;;;;GAKG;AACH,wBAAsB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"introspection.d.ts","sourceRoot":"","sources":["../../src/helpers/introspection.ts"],"names":[],"mappings":"AAcA;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,mBAiBjC;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,MAAM,mBASxD;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,mBAGvD;AAkBD,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAK,EACpC,SAAS,EAAE,MAAM,EAAE,mBAsFpB"}
|
|
@@ -15,21 +15,16 @@ const promises_1 = require("node:fs/promises");
|
|
|
15
15
|
async function introspectEndpoint(endpoint, headers) {
|
|
16
16
|
const response = await fetch(endpoint, {
|
|
17
17
|
method: "POST",
|
|
18
|
-
headers: {
|
|
19
|
-
"Content-Type": "application/json",
|
|
20
|
-
...headers,
|
|
21
|
-
},
|
|
18
|
+
headers: { "Content-Type": "application/json", ...headers },
|
|
22
19
|
body: JSON.stringify({
|
|
23
|
-
query: (0, graphql_1.getIntrospectionQuery)(),
|
|
20
|
+
query: (0, graphql_1.getIntrospectionQuery)(), // Removed invalid options
|
|
24
21
|
}),
|
|
25
22
|
});
|
|
26
23
|
if (!response.ok) {
|
|
27
24
|
throw new Error(`GraphQL request failed: ${response.statusText}`);
|
|
28
25
|
}
|
|
29
26
|
const responseJson = await response.json();
|
|
30
|
-
// Transform to a schema object
|
|
31
27
|
const schema = (0, graphql_1.buildClientSchema)(responseJson.data);
|
|
32
|
-
// Print the schema SDL
|
|
33
28
|
return (0, graphql_1.printSchema)(schema);
|
|
34
29
|
}
|
|
35
30
|
/**
|
|
@@ -84,12 +79,18 @@ async function introspectTypes(endpoint, headers = {}, typeNames) {
|
|
|
84
79
|
result[name] = {
|
|
85
80
|
kind: type instanceof graphql_1.GraphQLObjectType ? "OBJECT" : "INTERFACE",
|
|
86
81
|
description: type.description,
|
|
87
|
-
fields: Object.fromEntries(Object.entries(type.getFields())
|
|
82
|
+
fields: Object.fromEntries(Object.entries(type.getFields())
|
|
83
|
+
// Filter out deprecated fields
|
|
84
|
+
.filter(([_, field]) => !field.deprecationReason)
|
|
85
|
+
.map(([fieldName, field]) => [
|
|
88
86
|
fieldName,
|
|
89
87
|
{
|
|
90
88
|
type: field.type.toString(),
|
|
91
89
|
description: field.description,
|
|
92
|
-
args: field.args
|
|
90
|
+
args: field.args
|
|
91
|
+
// Filter out deprecated arguments
|
|
92
|
+
.filter(arg => !arg.deprecationReason)
|
|
93
|
+
.map(arg => ({
|
|
93
94
|
name: arg.name,
|
|
94
95
|
type: arg.type.toString(),
|
|
95
96
|
description: arg.description,
|
|
@@ -122,7 +123,10 @@ async function introspectTypes(endpoint, headers = {}, typeNames) {
|
|
|
122
123
|
result[name] = {
|
|
123
124
|
kind: "INPUT_OBJECT",
|
|
124
125
|
description: type.description,
|
|
125
|
-
fields: Object.fromEntries(Object.entries(type.getFields())
|
|
126
|
+
fields: Object.fromEntries(Object.entries(type.getFields())
|
|
127
|
+
// FILTER: Skip deprecated input fields
|
|
128
|
+
.filter(([_, field]) => !field.deprecationReason)
|
|
129
|
+
.map(([fieldName, field]) => [
|
|
126
130
|
fieldName,
|
|
127
131
|
{ type: field.type.toString(), description: field.description }
|
|
128
132
|
]))
|
package/dist/index.js
CHANGED
|
@@ -122,10 +122,7 @@ const introspectSchemaHandler = async ({ typeNames, descriptions = true, directi
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
catch (error) {
|
|
125
|
-
|
|
126
|
-
isError: true,
|
|
127
|
-
content: [{ type: "text", text: `Introspection failed: ${error}` }],
|
|
128
|
-
};
|
|
125
|
+
throw new Error(`Introspection failed: ${error}`); // ✅ Throw instead
|
|
129
126
|
}
|
|
130
127
|
};
|
|
131
128
|
toolHandlers.set("introspect-schema", introspectSchemaHandler);
|
|
@@ -139,27 +136,11 @@ const queryGraphqlHandler = async ({ query, variables, headers }) => {
|
|
|
139
136
|
const parsedQuery = parse(query);
|
|
140
137
|
const isMutation = parsedQuery.definitions.some((def) => def.kind === "OperationDefinition" && def.operation === "mutation");
|
|
141
138
|
if (isMutation && !env.ALLOW_MUTATIONS) {
|
|
142
|
-
|
|
143
|
-
isError: true,
|
|
144
|
-
content: [
|
|
145
|
-
{
|
|
146
|
-
type: "text",
|
|
147
|
-
text: "Mutations are not allowed unless you enable them in the configuration. Please use a query operation instead.",
|
|
148
|
-
},
|
|
149
|
-
],
|
|
150
|
-
};
|
|
139
|
+
throw new Error("Mutations are not allowed unless you enable them in the configuration. Please use a query operation instead.");
|
|
151
140
|
}
|
|
152
141
|
}
|
|
153
142
|
catch (error) {
|
|
154
|
-
|
|
155
|
-
isError: true,
|
|
156
|
-
content: [
|
|
157
|
-
{
|
|
158
|
-
type: "text",
|
|
159
|
-
text: `Invalid GraphQL query: ${error}`,
|
|
160
|
-
},
|
|
161
|
-
],
|
|
162
|
-
};
|
|
143
|
+
throw new Error(`Invalid GraphQL query: ${error}`);
|
|
163
144
|
}
|
|
164
145
|
try {
|
|
165
146
|
const toolHeaders = headers
|
|
@@ -189,28 +170,12 @@ const queryGraphqlHandler = async ({ query, variables, headers }) => {
|
|
|
189
170
|
});
|
|
190
171
|
if (!response.ok) {
|
|
191
172
|
const responseText = await response.text();
|
|
192
|
-
|
|
193
|
-
isError: true,
|
|
194
|
-
content: [
|
|
195
|
-
{
|
|
196
|
-
type: "text",
|
|
197
|
-
text: `GraphQL request failed: ${response.statusText}\n${responseText}`,
|
|
198
|
-
},
|
|
199
|
-
],
|
|
200
|
-
};
|
|
173
|
+
throw new Error(`GraphQL request failed: ${response.statusText}\n${responseText}`);
|
|
201
174
|
}
|
|
202
175
|
const rawData = await response.json();
|
|
203
176
|
const data = rawData;
|
|
204
177
|
if (data.errors && data.errors.length > 0) {
|
|
205
|
-
|
|
206
|
-
isError: true,
|
|
207
|
-
content: [
|
|
208
|
-
{
|
|
209
|
-
type: "text",
|
|
210
|
-
text: `GraphQL errors: ${JSON.stringify(data.errors, null, 2)}`,
|
|
211
|
-
},
|
|
212
|
-
],
|
|
213
|
-
};
|
|
178
|
+
throw new Error(`GraphQL errors: ${JSON.stringify(data.errors, null, 2)}`);
|
|
214
179
|
}
|
|
215
180
|
return {
|
|
216
181
|
content: [
|
|
@@ -222,15 +187,7 @@ const queryGraphqlHandler = async ({ query, variables, headers }) => {
|
|
|
222
187
|
};
|
|
223
188
|
}
|
|
224
189
|
catch (error) {
|
|
225
|
-
|
|
226
|
-
isError: true,
|
|
227
|
-
content: [
|
|
228
|
-
{
|
|
229
|
-
type: "text",
|
|
230
|
-
text: `Failed to execute GraphQL query: ${error}`,
|
|
231
|
-
},
|
|
232
|
-
],
|
|
233
|
-
};
|
|
190
|
+
throw new Error(`Failed to execute GraphQL query: ${error}`);
|
|
234
191
|
}
|
|
235
192
|
};
|
|
236
193
|
toolHandlers.set("query-graphql", queryGraphqlHandler);
|
|
@@ -371,9 +328,15 @@ async function startHttpServer(initialPort) {
|
|
|
371
328
|
});
|
|
372
329
|
}
|
|
373
330
|
async function main() {
|
|
331
|
+
// Pre-load schema FIRST (parallel with server setup)
|
|
332
|
+
console.error(`[SCHEMA] Pre-loading GraphQL schema...`);
|
|
333
|
+
const schemaPromise = getSchema().catch((error) => {
|
|
334
|
+
console.error(`[SCHEMA] Warning: Failed to pre-load schema: ${error}`);
|
|
335
|
+
});
|
|
374
336
|
const stdioTransport = new StdioServerTransport();
|
|
375
337
|
await server.connect(stdioTransport);
|
|
376
|
-
|
|
338
|
+
console.error(`[STDIO] Started GraphQL MCP server ${env.NAME} for endpoint: ${env.ENDPOINT}`);
|
|
339
|
+
// Only start HTTP if needed
|
|
377
340
|
if (env.ENABLE_HTTP) {
|
|
378
341
|
try {
|
|
379
342
|
const port = await startHttpServer(env.MCP_PORT);
|
|
@@ -381,18 +344,13 @@ async function main() {
|
|
|
381
344
|
}
|
|
382
345
|
catch (error) {
|
|
383
346
|
console.error(`[HTTP] Failed to start HTTP server: ${error}`);
|
|
384
|
-
// Don't exit - STDIO transport is more important
|
|
385
347
|
}
|
|
386
348
|
}
|
|
387
349
|
else {
|
|
388
350
|
console.error(`[HTTP] HTTP transport disabled (ENABLE_HTTP=auto|true to enable)`);
|
|
389
351
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
}
|
|
393
|
-
catch (error) {
|
|
394
|
-
console.error(`[SCHEMA] Warning: Failed to pre-load schema: ${error}`);
|
|
395
|
-
}
|
|
352
|
+
// Wait for schema to finish loading
|
|
353
|
+
await schemaPromise;
|
|
396
354
|
}
|
|
397
355
|
// Graceful shutdown
|
|
398
356
|
process.on('SIGINT', () => {
|
package/package.json
CHANGED