@letoribo/mcp-graphql-enhanced 2.0.5

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Boris Besemer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # mcp-graphql-enhanced
2
+
3
+ [![Smithery](https://smithery.ai/badge/mcp-graphql-enhanced)](https://smithery.ai/server/mcp-graphql-enhanced)
4
+ [![Glama](https://glama.ai/mcp/servers/@letoribo/mcp-graphql-enhanced)](https://glama.ai/mcp/servers/@letoribo/mcp-graphql-enhanced)
5
+
6
+ An **enhanced MCP (Model Context Protocol) server for GraphQL** that fixes real-world interoperability issues between LLMs and GraphQL APIs.
7
+
8
+ > Drop-in replacement for `mcp-graphql` — with dynamic headers, robust variables parsing, and zero breaking changes.
9
+
10
+ ## ✨ Key Enhancements
11
+
12
+ - ✅ **Dynamic headers** — pass `Authorization`, `X-API-Key`, etc., via tool arguments (no config restarts)
13
+ - ✅ **Robust variables parsing** — fixes `“Query variables must be a null or an object”` error
14
+ - ✅ **Full MCP compatibility** — works with **Claude Desktop**, **Cursor**, **Glama**, and **Smithery**
15
+ - ✅ **Secure by default** — mutations disabled unless explicitly enabled
16
+
17
+ ## 🔍 Debug & Inspect
18
+
19
+ Use the official MCP Inspector to test your server live:
20
+
21
+ ```bash
22
+ npx @modelcontextprotocol/inspector \
23
+ -e ENDPOINT=https://api.example.com/graphql \
24
+ npx mcp-graphql-enhanced --debug
25
+ ```
26
+
27
+ ### Environment Variables (Breaking change in 1.0.0)
28
+
29
+ > **Note:** As of version 1.0.0, command line arguments have been replaced with environment variables.
30
+
31
+ | Environment Variable | Description | Default |
32
+ |----------|-------------|---------|
33
+ | `ENDPOINT` | GraphQL endpoint URL | `http://localhost:4000/graphql` |
34
+ | `HEADERS` | JSON string containing headers for requests | `{}` |
35
+ | `ALLOW_MUTATIONS` | Enable mutation operations (disabled by default) | `false` |
36
+ | `NAME` | Name of the MCP server | `mcp-graphql-enhanced` |
37
+ | `SCHEMA` | Path to a local GraphQL schema file or URL (optional) | - |
38
+
39
+ ### Examples
40
+
41
+ ```bash
42
+ # Basic usage
43
+ ENDPOINT=http://localhost:3000/graphql npx mcp-graphql-enhanced
44
+
45
+ # With auth header
46
+ ENDPOINT=https://api.example.com/graphql \
47
+ HEADERS='{"Authorization":"Bearer xyz"}' \
48
+ npx mcp-graphql-enhanced
49
+
50
+ # Enable mutations
51
+ ENDPOINT=http://localhost:3000/graphql \
52
+ ALLOW_MUTATIONS=true \
53
+ npx mcp-graphql-enhanced
54
+
55
+ # Use local schema file
56
+ ENDPOINT=http://localhost:3000/graphql \
57
+ SCHEMA=./schema.graphql \
58
+ npx mcp-graphql-enhanced
59
+ ```
60
+
61
+ ## Resources
62
+
63
+ - **graphql-schema**: The server exposes the GraphQL schema as a resource that clients can access. This is either the local schema file, a schema file hosted at a URL, or based on an introspection query.
64
+
65
+ ## Available Tools
66
+
67
+ The server provides two main tools:
68
+
69
+ 1. **introspect-schema**: This tool retrieves the GraphQL schema. Use this first if you don't have access to the schema as a resource.
70
+ This uses either the local schema file, a schema file hosted at a URL, or an introspection query.
71
+
72
+ 2. **query-graphql**: Execute GraphQL queries against the endpoint. By default, mutations are disabled unless `ALLOW_MUTATIONS` is set to `true`.
73
+
74
+ ## Installation
75
+
76
+ ### Installing via Smithery
77
+
78
+ To install GraphQL MCP Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/mcp-graphql-enhanced):
79
+
80
+ ```bash
81
+ npx -y @smithery/cli install mcp-graphql-enhanced --client claude
82
+ ```
83
+
84
+ ### Installing Manually
85
+
86
+ It can be manually installed to Claude:
87
+ ```json
88
+ {
89
+ "mcpServers": {
90
+ "mcp-graphql": {
91
+ "command": "npx",
92
+ "args": ["mcp-graphql-enhanced"],
93
+ "env": {
94
+ "ENDPOINT": "https://your-api.com/graphql"
95
+ }
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ## Security Considerations
102
+
103
+ Mutations are disabled by default to prevent unintended data changes. Always validate HEADERS and SCHEMA inputs in production. Use HTTPS endpoints and short-lived tokens where possible.
104
+ ## Customize for your own server
105
+
106
+ This is a very generic implementation where it allows for complete introspection and for your users to do whatever (including mutations). If you need a more specific implementation I'd suggest to just create your own MCP and lock down tool calling for clients to only input specific query fields and/or variables. You can use this as a reference.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Helper module for handling deprecation warnings
3
+ */
4
+ /**
5
+ * Check for deprecated command line arguments and output warnings
6
+ */
7
+ export declare function checkDeprecatedArguments(): void;
8
+ //# sourceMappingURL=deprecation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deprecation.d.ts","sourceRoot":"","sources":["../../src/helpers/deprecation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CA0B/C"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /**
3
+ * Helper module for handling deprecation warnings
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.checkDeprecatedArguments = checkDeprecatedArguments;
7
+ /**
8
+ * Check for deprecated command line arguments and output warnings
9
+ */
10
+ function checkDeprecatedArguments() {
11
+ const deprecatedArgs = [
12
+ "--endpoint",
13
+ "--headers",
14
+ "--enable-mutations",
15
+ "--name",
16
+ "--schema",
17
+ ];
18
+ const usedDeprecatedArgs = deprecatedArgs.filter((arg) => process.argv.includes(arg));
19
+ if (usedDeprecatedArgs.length > 0) {
20
+ console.error(`WARNING: Deprecated command line arguments detected: ${usedDeprecatedArgs.join(", ")}`);
21
+ console.error("As of version 1.0.0, command line arguments have been replaced with environment variables.");
22
+ console.error("Please use environment variables instead. For example:");
23
+ console.error(" Instead of: npx mcp-graphql --endpoint http://example.com/graphql");
24
+ console.error(" Use: ENDPOINT=http://example.com/graphql npx mcp-graphql");
25
+ console.error("");
26
+ }
27
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Parse and merge headers from various sources
3
+ * @param configHeaders - Default headers from configuration
4
+ * @param inputHeaders - Headers provided by the user (string or object)
5
+ * @returns Merged headers object
6
+ */
7
+ export declare function parseAndMergeHeaders(configHeaders: Record<string, string>, inputHeaders?: string | Record<string, string>): Record<string, string>;
8
+ //# sourceMappingURL=headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/helpers/headers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,oBAAoB,CACnC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBxB"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseAndMergeHeaders = parseAndMergeHeaders;
4
+ /**
5
+ * Parse and merge headers from various sources
6
+ * @param configHeaders - Default headers from configuration
7
+ * @param inputHeaders - Headers provided by the user (string or object)
8
+ * @returns Merged headers object
9
+ */
10
+ function parseAndMergeHeaders(configHeaders, inputHeaders) {
11
+ // Parse headers if they're provided as a string
12
+ let parsedHeaders = {};
13
+ if (typeof inputHeaders === "string") {
14
+ try {
15
+ parsedHeaders = JSON.parse(inputHeaders);
16
+ }
17
+ catch (e) {
18
+ throw new Error(`Invalid headers JSON: ${e}`);
19
+ }
20
+ }
21
+ else if (inputHeaders) {
22
+ parsedHeaders = inputHeaders;
23
+ }
24
+ // Merge with config headers (config headers are overridden by input headers)
25
+ return { ...configHeaders, ...parsedHeaders };
26
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Introspect a GraphQL endpoint and return the schema as the GraphQL SDL
3
+ * @param endpoint - The endpoint to introspect
4
+ * @param headers - Optional headers to include in the request
5
+ * @returns The schema
6
+ */
7
+ export declare function introspectEndpoint(endpoint: string, headers?: Record<string, string>): Promise<string>;
8
+ /**
9
+ * Introspect a GraphQL schema file hosted at a URL and return the schema as the GraphQL SDL
10
+ * @param url - The URL to the schema file
11
+ * @returns The schema
12
+ */
13
+ export declare function introspectSchemaFromUrl(url: string): Promise<string>;
14
+ /**
15
+ * Introspect a local GraphQL schema file and return the schema as the GraphQL SDL
16
+ * @param path - The path to the local schema file
17
+ * @returns The schema
18
+ */
19
+ export declare function introspectLocalSchema(path: string): Promise<string>;
20
+ //# sourceMappingURL=introspection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspection.d.ts","sourceRoot":"","sources":["../../src/helpers/introspection.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACvC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,mBAuBhC;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,MAAM,mBASxD;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,mBAGvD"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.introspectEndpoint = introspectEndpoint;
4
+ exports.introspectSchemaFromUrl = introspectSchemaFromUrl;
5
+ exports.introspectLocalSchema = introspectLocalSchema;
6
+ const graphql_1 = require("graphql");
7
+ const promises_1 = require("node:fs/promises");
8
+ /**
9
+ * Introspect a GraphQL endpoint and return the schema as the GraphQL SDL
10
+ * @param endpoint - The endpoint to introspect
11
+ * @param headers - Optional headers to include in the request
12
+ * @returns The schema
13
+ */
14
+ async function introspectEndpoint(endpoint, headers) {
15
+ const response = await fetch(endpoint, {
16
+ method: "POST",
17
+ headers: {
18
+ "Content-Type": "application/json",
19
+ ...headers,
20
+ },
21
+ body: JSON.stringify({
22
+ query: (0, graphql_1.getIntrospectionQuery)(),
23
+ }),
24
+ });
25
+ if (!response.ok) {
26
+ throw new Error(`GraphQL request failed: ${response.statusText}`);
27
+ }
28
+ const responseJson = await response.json();
29
+ // Transform to a schema object
30
+ const schema = (0, graphql_1.buildClientSchema)(responseJson.data);
31
+ // Print the schema SDL
32
+ return (0, graphql_1.printSchema)(schema);
33
+ }
34
+ /**
35
+ * Introspect a GraphQL schema file hosted at a URL and return the schema as the GraphQL SDL
36
+ * @param url - The URL to the schema file
37
+ * @returns The schema
38
+ */
39
+ async function introspectSchemaFromUrl(url) {
40
+ const response = await fetch(url);
41
+ if (!response.ok) {
42
+ throw new Error(`Failed to fetch schema from URL: ${response.statusText}`);
43
+ }
44
+ const schema = await response.text();
45
+ return schema;
46
+ }
47
+ /**
48
+ * Introspect a local GraphQL schema file and return the schema as the GraphQL SDL
49
+ * @param path - The path to the local schema file
50
+ * @returns The schema
51
+ */
52
+ async function introspectLocalSchema(path) {
53
+ const schema = await (0, promises_1.readFile)(path, "utf8");
54
+ return schema;
55
+ }
@@ -0,0 +1,2 @@
1
+ export declare function getVersion(): any;
2
+ //# sourceMappingURL=package.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../src/helpers/package.ts"],"names":[],"mappings":"AAOA,wBAAgB,UAAU,QAEzB"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getVersion = getVersion;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const packageJson = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, "../../package.json"), "utf-8"));
7
+ function getVersion() {
8
+ return packageJson.version;
9
+ }
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ declare const McpServer: any;
3
+ declare const StdioServerTransport: any;
4
+ declare const parse: any;
5
+ declare const z: any;
6
+ declare const checkDeprecatedArguments: any;
7
+ declare const introspectEndpoint: any, introspectLocalSchema: any, introspectSchemaFromUrl: any;
8
+ declare const getVersion: () => any;
9
+ declare const EnvSchema: any;
10
+ declare const env: any;
11
+ declare const server: any;
12
+ declare function main(): Promise<void>;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,QAAA,MAAQ,SAAS,KAAuD,CAAC;AACzE,QAAA,MAAQ,oBAAoB,KAAyD,CAAC;AACtF,QAAA,MAAQ,KAAK,KAAgC,CAAC;AAC9C,QAAA,MAAM,CAAC,KAAyB,CAAC;AACjC,QAAA,MAAQ,wBAAwB,KAAwC,CAAC;AACzE,QAAA,MACC,kBAAkB,OAClB,qBAAqB,OACrB,uBAAuB,KACiB,CAAC;AAG1C,QAAA,MAAM,UAAU,WAIf,CAAC;AAKF,QAAA,MAAM,SAAS,KAkBb,CAAC;AAEH,QAAA,MAAM,GAAG,KAA+B,CAAC;AAEzC,QAAA,MAAM,MAAM,KAIV,CAAC;AAoMH,iBAAe,IAAI,kBAOlB"}
package/dist/index.js ADDED
@@ -0,0 +1,222 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js");
4
+ const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js");
5
+ const { parse } = require("graphql/language");
6
+ const z = require("zod").default;
7
+ const { checkDeprecatedArguments } = require("./helpers/deprecation.js");
8
+ const { introspectEndpoint, introspectLocalSchema, introspectSchemaFromUrl, } = require("./helpers/introspection.js");
9
+ // Simulate macro import — since "with { type: 'macro' }" is not CommonJS compatible
10
+ const getVersion = () => {
11
+ // Replace with your actual version or read from package.json
12
+ const pkg = require("../package.json");
13
+ return pkg.version;
14
+ };
15
+ // Check for deprecated command line arguments
16
+ checkDeprecatedArguments();
17
+ const EnvSchema = z.object({
18
+ NAME: z.string().default("mcp-graphql"),
19
+ ENDPOINT: z.string().url().default("http://localhost:4000/graphql"),
20
+ ALLOW_MUTATIONS: z
21
+ .enum(["true", "false"])
22
+ .transform((value) => value === "true")
23
+ .default("false"),
24
+ HEADERS: z
25
+ .string()
26
+ .default("{}")
27
+ .transform((val) => {
28
+ try {
29
+ return JSON.parse(val);
30
+ }
31
+ catch (e) {
32
+ throw new Error("HEADERS must be a valid JSON string");
33
+ }
34
+ }),
35
+ SCHEMA: z.string().optional(),
36
+ });
37
+ const env = EnvSchema.parse(process.env);
38
+ const server = new McpServer({
39
+ name: env.NAME,
40
+ version: getVersion(),
41
+ description: `GraphQL MCP server for ${env.ENDPOINT}`,
42
+ });
43
+ server.resource("graphql-schema", new URL(env.ENDPOINT).href, async (uri) => {
44
+ try {
45
+ let schema;
46
+ if (env.SCHEMA) {
47
+ if (env.SCHEMA.startsWith("http://") ||
48
+ env.SCHEMA.startsWith("https://")) {
49
+ schema = await introspectSchemaFromUrl(env.SCHEMA);
50
+ }
51
+ else {
52
+ schema = await introspectLocalSchema(env.SCHEMA);
53
+ }
54
+ }
55
+ else {
56
+ schema = await introspectEndpoint(env.ENDPOINT, env.HEADERS);
57
+ }
58
+ return {
59
+ contents: [
60
+ {
61
+ uri: uri.href,
62
+ text: schema,
63
+ },
64
+ ],
65
+ };
66
+ }
67
+ catch (error) {
68
+ throw new Error(`Failed to get GraphQL schema: ${error}`);
69
+ }
70
+ });
71
+ server.tool("introspect-schema", "Introspect the GraphQL schema, use this tool before doing a query to get the schema information if you do not have it available as a resource already.", {
72
+ __ignore__: z
73
+ .boolean()
74
+ .default(false)
75
+ .describe("This does not do anything"),
76
+ }, async () => {
77
+ try {
78
+ let schema;
79
+ if (env.SCHEMA) {
80
+ schema = await introspectLocalSchema(env.SCHEMA);
81
+ }
82
+ else {
83
+ schema = await introspectEndpoint(env.ENDPOINT, env.HEADERS);
84
+ }
85
+ return {
86
+ content: [
87
+ {
88
+ type: "text",
89
+ text: schema,
90
+ },
91
+ ],
92
+ };
93
+ }
94
+ catch (error) {
95
+ return {
96
+ isError: true,
97
+ content: [
98
+ {
99
+ type: "text",
100
+ text: `Failed to introspect schema: ${error}`,
101
+ },
102
+ ],
103
+ };
104
+ }
105
+ });
106
+ server.tool("query-graphql", "Query a GraphQL endpoint with the given query and variables. Optionally pass headers (e.g., for Authorization).", {
107
+ query: z.string(),
108
+ variables: z.string().optional(),
109
+ headers: z
110
+ .string()
111
+ .optional()
112
+ .describe("Optional JSON string of headers to include, e.g., {\"Authorization\": \"Bearer ...\"}"),
113
+ }, async ({ query, variables, headers }) => {
114
+ try {
115
+ const parsedQuery = parse(query);
116
+ const isMutation = parsedQuery.definitions.some((def) => def.kind === "OperationDefinition" && def.operation === "mutation");
117
+ if (isMutation && !env.ALLOW_MUTATIONS) {
118
+ return {
119
+ isError: true,
120
+ content: [
121
+ {
122
+ type: "text",
123
+ text: "Mutations are not allowed unless you enable them in the configuration. Please use a query operation instead.",
124
+ },
125
+ ],
126
+ };
127
+ }
128
+ }
129
+ catch (error) {
130
+ return {
131
+ isError: true,
132
+ content: [
133
+ {
134
+ type: "text",
135
+ text: `Invalid GraphQL query: ${error}`,
136
+ },
137
+ ],
138
+ };
139
+ }
140
+ try {
141
+ const toolHeaders = headers
142
+ ? JSON.parse(headers)
143
+ : {};
144
+ const allHeaders = {
145
+ "Content-Type": "application/json",
146
+ ...env.HEADERS,
147
+ ...toolHeaders,
148
+ };
149
+ // Parse variables if it's a string
150
+ let parsedVariables = null;
151
+ if (variables) {
152
+ if (typeof variables === 'string') {
153
+ parsedVariables = JSON.parse(variables);
154
+ }
155
+ else {
156
+ parsedVariables = variables;
157
+ }
158
+ }
159
+ const response = await fetch(env.ENDPOINT, {
160
+ method: "POST",
161
+ headers: allHeaders,
162
+ body: JSON.stringify({
163
+ query,
164
+ variables: parsedVariables,
165
+ }),
166
+ });
167
+ if (!response.ok) {
168
+ const responseText = await response.text();
169
+ return {
170
+ isError: true,
171
+ content: [
172
+ {
173
+ type: "text",
174
+ text: `GraphQL request failed: ${response.statusText}\n${responseText}`,
175
+ },
176
+ ],
177
+ };
178
+ }
179
+ const rawData = await response.json();
180
+ // Type assertion for quick dev (replace with zod validation later)
181
+ const data = rawData;
182
+ if (data.errors && data.errors.length > 0) {
183
+ return {
184
+ isError: true,
185
+ content: [
186
+ {
187
+ type: "text",
188
+ text: `GraphQL errors: ${JSON.stringify(data.errors, null, 2)}`,
189
+ },
190
+ ],
191
+ };
192
+ }
193
+ return {
194
+ content: [
195
+ {
196
+ type: "text",
197
+ text: JSON.stringify(data, null, 2),
198
+ },
199
+ ],
200
+ };
201
+ }
202
+ catch (error) {
203
+ return {
204
+ isError: true,
205
+ content: [
206
+ {
207
+ type: "text",
208
+ text: `Failed to execute GraphQL query: ${error}`,
209
+ },
210
+ ],
211
+ };
212
+ }
213
+ });
214
+ async function main() {
215
+ const transport = new StdioServerTransport();
216
+ await server.connect(transport);
217
+ console.error(`Started graphql mcp server ${env.NAME} for endpoint: ${env.ENDPOINT}`);
218
+ }
219
+ main().catch((error) => {
220
+ console.error(`Fatal error in main(): ${error}`);
221
+ process.exit(1);
222
+ });
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@letoribo/mcp-graphql-enhanced",
3
+ "description": "Enhanced MCP server for GraphQL with dynamic headers and robust variables parsing — a drop-in replacement for mcp-graphql.",
4
+ "keywords": [
5
+ "mcp",
6
+ "graphql",
7
+ "llm",
8
+ "claude-desktop",
9
+ "cursor",
10
+ "enhanced",
11
+ "tool-calling"
12
+ ],
13
+ "author": "letoribo",
14
+ "license": "MIT",
15
+ "repository": "github:letoribo/mcp-graphql-enhanced",
16
+ "main": "dist/index.js",
17
+ "types": "dist/index.d.ts",
18
+ "bin": {
19
+ "mcp-graphql-enhanced": "./dist/index.js"
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "engines": {
25
+ "node": ">=18"
26
+ },
27
+ "scripts": {
28
+ "dev": "ts-node src/index.ts",
29
+ "build": "tsc && chmod +x dist/index.js",
30
+ "start": "node dist/index.js",
31
+ "format": "prettier --write ."
32
+ },
33
+ "dependencies": {
34
+ "@modelcontextprotocol/sdk": "1.12.0",
35
+ "graphql": "^16.11.0",
36
+ "yargs": "17.7.2",
37
+ "zod": "3.25.30",
38
+ "zod-to-json-schema": "3.24.5"
39
+ },
40
+ "devDependencies": {
41
+ "@graphql-tools/schema": "^10.0.23",
42
+ "@types/node": "^24.7.2",
43
+ "@types/yargs": "17.0.33",
44
+ "graphql-yoga": "^5.13.5",
45
+ "prettier": "^3.6.2",
46
+ "ts-node": "^10.9.2",
47
+ "typescript": "5.8.3"
48
+ },
49
+ "version": "2.0.5"
50
+ }