@letoribo/mcp-graphql-enhanced 3.2.1 → 3.3.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 CHANGED
@@ -4,6 +4,7 @@ An **enhanced MCP (Model Context Protocol) server for GraphQL** that fixes real-
4
4
  > Drop-in replacement for `mcp-graphql` — with dynamic headers, robust variables parsing, and zero breaking changes.
5
5
 
6
6
  ## ✨ Key Enhancements
7
+ * ✅ **Built-in GraphiQL IDE** — Visual playground at http://localhost:MCP_PORT/ (or /graphiql) with pre-configured headers.
7
8
  * ✅ **Dual Transport** — Supports both **STDIO** (for local CLI/client tools) and **HTTP/JSON-RPC** (for external/browser clients).
8
9
  * ✅ **Dynamic headers** — pass `Authorization`, `X-API-Key`, etc., via tool arguments (no config restarts)
9
10
  * ✅ **Robust variables parsing** — fixes `“Query variables must be a null or an object”` error
@@ -12,6 +13,11 @@ An **enhanced MCP (Model Context Protocol) server for GraphQL** that fixes real-
12
13
  * ✅ **Secure by default** — mutations disabled unless explicitly enabled
13
14
 
14
15
  ---
16
+ ## 🎨 Visual Command Center (GraphiQL)
17
+ Unlike standard MCP servers, this one provides a visual interface for humans. When running with `ENABLE_HTTP=true`, you can open a full-featured **GraphiQL IDE** in your browser.
18
+
19
+ * **Endpoint:** `http://localhost:6274/` (or `/graphiql`)
20
+ * **Header Sync:** Any headers set in your environment (like GitHub tokens) are automatically injected into the GraphiQL "Headers" tab for immediate testing.
15
21
 
16
22
  ## 💻 HTTP / Dual Transport
17
23
 
@@ -21,6 +27,7 @@ This allows external systems, web applications, and direct `curl` commands to ac
21
27
 
22
28
  | **Endpoint** | **Method** | **Description** |
23
29
  | :--- | :--- | :--- |
30
+ | `/graphiql` | `GET` | Human Interface: The visual GraphQL IDE. |
24
31
  | `/mcp` | `POST` | The main JSON-RPC 2.0 endpoint for tool execution. |
25
32
  | `/health` | `GET` | Simple health check, returns `{ status: 'ok' }`. |
26
33
 
@@ -46,21 +53,21 @@ curl http://localhost:6274/health
46
53
  # Example: Test the query tool via JSON-RPC (using port 6275 if 6274 was busy)
47
54
  curl -X POST http://localhost:6275/mcp -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"query-graphql","params":{"query":"query { __typename }"},"id":1}'
48
55
 
49
- ## 🔍 Filtered Introspection (New!)
56
+ ## 🔍 Filtered Introspection
50
57
  Avoid 50k-line schema dumps. Ask for only what you need:
51
- ```@introspect-schema typeNames ["Query", "User"]```
58
+ `@introspect-schema typeNames ["Query", "User"]`
52
59
  ## 🔍 Debug & Inspect
53
60
  Use the official MCP Inspector to test your server live:
54
61
  ```bash
55
62
  npx @modelcontextprotocol/inspector \
56
63
  -e ENDPOINT=https://api.example.com/graphql \
57
- npx @letoribo/mcp-graphql-enhanced --debug
64
+ npx @letoribo/mcp-graphql-enhanced
58
65
  ```
59
66
  ### Environment Variables (Breaking change in 1.0.0)
60
67
  > **Note:** As of version 1.0.0, command line arguments have been replaced with environment variables.
61
68
 
62
69
  | Environment Variable | Description | Default |
63
- |----------|-------------|---------|
70
+ | :--- | :--- | :--- |
64
71
  | `ENDPOINT` | GraphQL endpoint URL | `https://mcp-neo4j-discord.vercel.app/api/graphiql` |
65
72
  | `HEADERS` | JSON string containing headers for requests | `{}` |
66
73
  | `ALLOW_MUTATIONS` | Enable mutation operations (disabled by default) | `false` |
@@ -93,6 +100,13 @@ npx @letoribo/mcp-graphql-enhanced
93
100
  MCP_PORT=8080 npx @letoribo/mcp-graphql-enhanced
94
101
  # Disable HTTP transport (fastest, recommended for Claude Desktop)
95
102
  ENABLE_HTTP=false npx @letoribo/mcp-graphql-enhanced
103
+ # Test the surgical precision and the IDE immediately:
104
+ ENDPOINT=https://api.github.com/graphql \
105
+ HEADERS='{"Authorization":"Bearer YOUR_GITHUB_TOKEN"}' \
106
+ ENABLE_HTTP=true \
107
+ npx @letoribo/mcp-graphql-enhanced
108
+
109
+ # Then visit http://localhost:6274/graphiql
96
110
  ```
97
111
  ### 🖥️ Claude Desktop Configuration Examples
98
112
  You can connect Claude Desktop to your GraphQL API using either the npx package (recommended for simplicity) or the Docker image (ideal for reproducibility and isolation).
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Renders the GraphiQL IDE template with visible headers
3
+ * @param endpoint The GraphQL API endpoint to connect to
4
+ * @param headers Optional default headers to inject into the editor
5
+ */
6
+ export declare function renderGraphiQL(endpoint: string, headers?: object): string;
7
+ //# sourceMappingURL=graphiql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphiql.d.ts","sourceRoot":"","sources":["../../src/helpers/graphiql.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GAAG,MAAM,CAoE7E"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderGraphiQL = renderGraphiQL;
4
+ /**
5
+ * Renders the GraphiQL IDE template with visible headers
6
+ * @param endpoint The GraphQL API endpoint to connect to
7
+ * @param headers Optional default headers to inject into the editor
8
+ */
9
+ function renderGraphiQL(endpoint, headers = {}) {
10
+ // Stringify headers for the injection into the script
11
+ const stringifiedHeaders = JSON.stringify(headers, null, 2);
12
+ return `
13
+ <!DOCTYPE html>
14
+ <html lang="en">
15
+ <head>
16
+ <meta charset="utf-8" />
17
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
18
+ <title>GraphiQL Explorer | Surgical MCP</title>
19
+ <link href="https://unpkg.com/graphiql@3.8.2/graphiql.min.css" rel="stylesheet" />
20
+ <style>
21
+ body {
22
+ margin: 0;
23
+ height: 100vh;
24
+ width: 100vw;
25
+ overflow: hidden;
26
+ background: #0b1016;
27
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
28
+ }
29
+ #graphiql { height: 100vh; }
30
+ .loading-screen {
31
+ color: white;
32
+ display: flex;
33
+ justify-content: center;
34
+ align-items: center;
35
+ height: 100%;
36
+ font-size: 1.2rem;
37
+ }
38
+ </style>
39
+ </head>
40
+ <body>
41
+ <div id="graphiql">
42
+ <div class="loading-screen">Initializing Surgical GraphiQL...</div>
43
+ </div>
44
+
45
+ <script src="https://unpkg.com/react@18.2.0/umd/react.production.min.js" crossorigin referrerpolicy="no-referrer"></script>
46
+ <script src="https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js" crossorigin referrerpolicy="no-referrer"></script>
47
+ <script src="https://unpkg.com/graphiql@3.8.2/graphiql.min.js" crossorigin referrerpolicy="no-referrer"></script>
48
+
49
+ <script>
50
+ window.addEventListener('load', function() {
51
+ if (typeof GraphiQL !== 'undefined') {
52
+ const fetcher = GraphiQL.createFetcher({
53
+ url: '${endpoint}'
54
+ });
55
+
56
+ const root = ReactDOM.createRoot(document.getElementById('graphiql'));
57
+ root.render(
58
+ React.createElement(GraphiQL, {
59
+ fetcher: fetcher,
60
+ headerEditorEnabled: true,
61
+ shouldPersistHeaders: true,
62
+ // This makes the headers visible in the UI tab
63
+ defaultHeaders: \`${stringifiedHeaders}\`,
64
+ theme: 'dark',
65
+ defaultEditorToolsVisibility: true
66
+ })
67
+ );
68
+ } else {
69
+ document.getElementById('graphiql').innerHTML =
70
+ '<div class="loading-screen" style="color: #ff4d4d">Error: GraphiQL SDK failed to load.</div>';
71
+ }
72
+ });
73
+ </script>
74
+ </body>
75
+ </html>`;
76
+ }
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
9
9
  const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
10
10
  const language_1 = require("graphql/language");
11
11
  const zod_1 = __importDefault(require("zod"));
12
+ const graphiql_js_1 = require("./helpers/graphiql.js");
12
13
  // Helper imports
13
14
  const deprecation_js_1 = require("./helpers/deprecation.js");
14
15
  const introspection_js_1 = require("./helpers/introspection.js");
@@ -164,6 +165,12 @@ async function handleHttpRequest(req, res) {
164
165
  return;
165
166
  }
166
167
  const url = new URL(req.url || '', `http://${req.headers.host}`);
168
+ // NEW FEATURE: Web GUI for Humans
169
+ if (req.method === 'GET' && (url.pathname === '/' || url.pathname === '/graphiql')) {
170
+ res.writeHead(200, { 'Content-Type': 'text/html' });
171
+ // Pass env.HEADERS to the explorer
172
+ return res.end((0, graphiql_js_1.renderGraphiQL)(env.ENDPOINT, env.HEADERS));
173
+ }
167
174
  if (url.pathname === '/mcp' && req.method === 'POST') {
168
175
  let body = '';
169
176
  req.on('data', chunk => { body += chunk; });
@@ -201,6 +208,8 @@ async function main() {
201
208
  const serverHttp = node_http_1.default.createServer(handleHttpRequest);
202
209
  serverHttp.listen(env.MCP_PORT, () => {
203
210
  console.error(`[HTTP] Server started on http://localhost:${env.MCP_PORT}`);
211
+ console.error(`🎨 GraphiQL IDE: http://localhost:${env.MCP_PORT}/graphiql`);
212
+ console.error(`🤖 MCP Endpoint: http://localhost:${env.MCP_PORT}/mcp\n`);
204
213
  });
205
214
  }
206
215
  const transport = new stdio_js_1.StdioServerTransport();
package/package.json CHANGED
@@ -50,5 +50,5 @@
50
50
  "tsx": "^4.21.0",
51
51
  "typescript": "5.8.3"
52
52
  },
53
- "version": "3.2.1"
53
+ "version": "3.3.0"
54
54
  }