@cloudstreamsoftware/knowledge-mcp-client 1.0.0 → 1.0.1
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 +4 -4
- package/dist/index.js +61 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @cloudstreamsoftware/knowledge-mcp-client
|
|
2
2
|
|
|
3
3
|
MCP client bridge for CloudStream Knowledge Server. Translates Claude Code's stdio-based MCP protocol to HTTP requests against the Cloudflare Knowledge Server.
|
|
4
4
|
|
|
@@ -26,7 +26,7 @@ Add to `~/.claude/settings.json`:
|
|
|
26
26
|
"mcpServers": {
|
|
27
27
|
"cloudstream-knowledge": {
|
|
28
28
|
"command": "npx",
|
|
29
|
-
"args": ["@
|
|
29
|
+
"args": ["@cloudstreamsoftware/knowledge-mcp-client"],
|
|
30
30
|
"env": {
|
|
31
31
|
"CLOUDSTREAM_LICENSE": "your-license-key",
|
|
32
32
|
"CLOUDSTREAM_API": "https://cloudstream-knowledge.broken-rain-0984.workers.dev"
|
|
@@ -64,7 +64,7 @@ When the Knowledge Server is unavailable, the bridge returns helpful error messa
|
|
|
64
64
|
Enable debug logging:
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
|
-
CLOUDSTREAM_DEBUG=true npx @
|
|
67
|
+
CLOUDSTREAM_DEBUG=true npx @cloudstreamsoftware/knowledge-mcp-client
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
Debug output goes to stderr (doesn't interfere with JSON-RPC protocol on stdout).
|
|
@@ -75,7 +75,7 @@ Debug output goes to stderr (doesn't interfere with JSON-RPC protocol on stdout)
|
|
|
75
75
|
# Test initialize (no network required)
|
|
76
76
|
echo '{"jsonrpc":"2.0","id":1,"method":"initialize"}' | \
|
|
77
77
|
CLOUDSTREAM_LICENSE=test CLOUDSTREAM_API=http://localhost \
|
|
78
|
-
npx @
|
|
78
|
+
npx @cloudstreamsoftware/knowledge-mcp-client
|
|
79
79
|
|
|
80
80
|
# Expected response:
|
|
81
81
|
# {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05",...}}
|
package/dist/index.js
CHANGED
|
@@ -99,56 +99,78 @@ async function main() {
|
|
|
99
99
|
}
|
|
100
100
|
// Create HTTP bridge
|
|
101
101
|
const bridge = new bridge_1.HttpBridge(config);
|
|
102
|
+
// Track pending async operations to prevent premature exit
|
|
103
|
+
const pendingRequests = new Set();
|
|
104
|
+
let stdinClosed = false;
|
|
102
105
|
// Set up readline interface for stdin
|
|
103
106
|
const rl = readline.createInterface({
|
|
104
107
|
input: process.stdin,
|
|
105
108
|
terminal: false,
|
|
106
109
|
});
|
|
107
110
|
// Process JSON-RPC requests line by line
|
|
108
|
-
rl.on('line',
|
|
111
|
+
rl.on('line', (line) => {
|
|
109
112
|
debug(`Received: ${line.slice(0, 100)}...`);
|
|
110
113
|
if (!line.trim()) {
|
|
111
114
|
return; // Ignore empty lines
|
|
112
115
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
request
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
116
|
+
// Handle request asynchronously but track the promise
|
|
117
|
+
const requestPromise = (async () => {
|
|
118
|
+
let request;
|
|
119
|
+
try {
|
|
120
|
+
request = JSON.parse(line);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// Parse error
|
|
124
|
+
sendResponse({
|
|
125
|
+
jsonrpc: '2.0',
|
|
126
|
+
id: null,
|
|
127
|
+
error: {
|
|
128
|
+
code: -32700,
|
|
129
|
+
message: 'Parse error: Invalid JSON',
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// Forward to bridge and send response
|
|
135
|
+
try {
|
|
136
|
+
const response = await bridge.forward(request);
|
|
137
|
+
debug(`Response for ${request.method}: ${bridge.getConnectionState()}`);
|
|
138
|
+
sendResponse(response);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
// Unexpected error - should be handled by bridge
|
|
142
|
+
debug(`Unexpected error: ${error.message}`);
|
|
143
|
+
sendResponse({
|
|
144
|
+
jsonrpc: '2.0',
|
|
145
|
+
id: request.id,
|
|
146
|
+
error: {
|
|
147
|
+
code: -32603,
|
|
148
|
+
message: `Internal error: ${error.message}`,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
})();
|
|
153
|
+
// Track this request
|
|
154
|
+
pendingRequests.add(requestPromise);
|
|
155
|
+
requestPromise.finally(() => {
|
|
156
|
+
pendingRequests.delete(requestPromise);
|
|
157
|
+
// If stdin is closed and no pending requests, exit
|
|
158
|
+
if (stdinClosed && pendingRequests.size === 0) {
|
|
159
|
+
debug('All requests completed, exiting');
|
|
160
|
+
process.exit(0);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
147
163
|
});
|
|
148
|
-
// Handle stdin close
|
|
149
|
-
rl.on('close', () => {
|
|
150
|
-
debug(
|
|
151
|
-
|
|
164
|
+
// Handle stdin close - wait for pending requests before exiting
|
|
165
|
+
rl.on('close', async () => {
|
|
166
|
+
debug(`stdin closed, ${pendingRequests.size} pending requests`);
|
|
167
|
+
stdinClosed = true;
|
|
168
|
+
// If no pending requests, exit immediately
|
|
169
|
+
if (pendingRequests.size === 0) {
|
|
170
|
+
debug('No pending requests, exiting');
|
|
171
|
+
process.exit(0);
|
|
172
|
+
}
|
|
173
|
+
// Otherwise, requests will exit when they complete (see finally block above)
|
|
152
174
|
});
|
|
153
175
|
// Handle errors
|
|
154
176
|
process.on('uncaughtException', (error) => {
|
package/package.json
CHANGED