@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 +18 -4
- package/dist/helpers/graphiql.d.ts +7 -0
- package/dist/helpers/graphiql.d.ts.map +1 -0
- package/dist/helpers/graphiql.js +76 -0
- package/dist/index.js +9 -0
- package/package.json +1 -1
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
|
|
56
|
+
## 🔍 Filtered Introspection
|
|
50
57
|
Avoid 50k-line schema dumps. Ask for only what you need:
|
|
51
|
-
|
|
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
|
|
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