reportdash-datastore-mcp-claude-desktop 1.0.10 → 1.0.12

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.
Files changed (2) hide show
  1. package/index.js +58 -45
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -19,7 +19,7 @@ if (!API_KEY) {
19
19
  error: {
20
20
  code: -32600,
21
21
  message:
22
- 'REPORTDASH_API_KEY environment variable is required. Get your API key from ReportDash DataStore app settings.',
22
+ 'REPORTDASH_API_KEY environment variable is required. Get your API key from ReportDash DataStore > Destinations > API Access.',
23
23
  },
24
24
  id: null,
25
25
  }) + '\n'
@@ -100,6 +100,9 @@ function forwardToAPI(mcpRequest) {
100
100
 
101
101
  const body = JSON.stringify(mcpRequest);
102
102
 
103
+ const hasId = mcpRequest && Object.prototype.hasOwnProperty.call(mcpRequest, 'id');
104
+ const reqId = hasId ? mcpRequest.id : undefined;
105
+
103
106
  const options = {
104
107
  hostname: url.hostname,
105
108
  port: url.port || (isHttps ? 443 : 80),
@@ -118,82 +121,91 @@ function forwardToAPI(mcpRequest) {
118
121
  let data = '';
119
122
  res.on('data', (chunk) => (data += chunk));
120
123
  res.on('end', () => {
121
- const id = rpcId(mcpRequest);
124
+ // Notifications MUST NOT get responses
125
+ if (!hasId) return;
122
126
 
123
- // 204 or empty body => empty result
127
+ // 204 / empty => empty result
124
128
  if (res.statusCode === 204 || !data.trim()) {
125
129
  if (res.statusCode >= 200 && res.statusCode < 300) {
126
- writeJson({ jsonrpc: '2.0', id, result: {} });
130
+ process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: reqId, result: {} }) + '\n');
127
131
  } else {
128
- writeJson(
129
- rpcError({
130
- id,
131
- code: res.statusCode,
132
- message: `API error: ${res.statusCode} (empty body)`,
133
- })
132
+ process.stdout.write(
133
+ JSON.stringify({
134
+ jsonrpc: '2.0',
135
+ id: reqId,
136
+ error: { code: res.statusCode, message: `API error: ${res.statusCode} (empty body)` },
137
+ }) + '\n'
134
138
  );
135
139
  }
136
140
  return;
137
141
  }
138
142
 
139
- // Always re-serialize to 1-line JSON for MCP framing
140
143
  let parsed;
141
144
  try {
142
145
  parsed = JSON.parse(data);
143
146
  } catch (e) {
144
- writeJson(
145
- rpcError({
146
- id,
147
- code: res.statusCode >= 400 ? res.statusCode : -32603,
148
- message: 'API returned non-JSON response',
149
- data: { statusCode: res.statusCode, body: data },
150
- })
147
+ process.stdout.write(
148
+ JSON.stringify({
149
+ jsonrpc: '2.0',
150
+ id: reqId,
151
+ error: {
152
+ code: -32603,
153
+ message: 'API returned non-JSON response',
154
+ data: { statusCode: res.statusCode, body: data },
155
+ },
156
+ }) + '\n'
151
157
  );
152
158
  return;
153
159
  }
154
160
 
161
+ // Success
155
162
  if (res.statusCode >= 200 && res.statusCode < 300) {
156
- // Ensure JSON-RPC envelope exists; if your API returns raw jsonrpc objects, this is fine.
157
- // If it returns something else, wrap it.
163
+ // If backend returned a JSON-RPC object, enforce id
158
164
  if (parsed && typeof parsed === 'object' && parsed.jsonrpc === '2.0') {
159
- // Some backends might omit id; ensure it's present
160
- if (parsed.id === undefined) parsed.id = id;
161
- writeJson(parsed);
165
+ if (!Object.prototype.hasOwnProperty.call(parsed, 'id')) parsed.id = reqId;
166
+ // IMPORTANT: never allow null id
167
+ if (parsed.id === null) parsed.id = reqId;
168
+ process.stdout.write(JSON.stringify(parsed) + '\n');
162
169
  } else {
163
- writeJson({ jsonrpc: '2.0', id, result: parsed });
170
+ process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: reqId, result: parsed }) + '\n');
164
171
  }
165
172
  } else {
166
- writeJson(
167
- rpcError({
168
- id,
169
- code: res.statusCode,
170
- message: `API error: ${res.statusCode}`,
171
- data: parsed,
172
- })
173
+ // Error
174
+ process.stdout.write(
175
+ JSON.stringify({
176
+ jsonrpc: '2.0',
177
+ id: reqId,
178
+ error: {
179
+ code: res.statusCode,
180
+ message: `API error: ${res.statusCode}`,
181
+ data: parsed,
182
+ },
183
+ }) + '\n'
173
184
  );
174
185
  }
175
186
  });
176
187
  });
177
188
 
178
189
  req.on('error', (error) => {
179
- writeJson(
180
- rpcError({
181
- id: rpcId(mcpRequest),
182
- code: -32603,
183
- message: 'Network error: ' + error.message,
184
- data: { error: error.message },
185
- })
190
+ if (!hasId) return; // notification: no response
191
+ process.stdout.write(
192
+ JSON.stringify({
193
+ jsonrpc: '2.0',
194
+ id: reqId,
195
+ error: { code: -32603, message: 'Network error: ' + error.message },
196
+ }) + '\n'
186
197
  );
187
198
  });
188
199
 
189
200
  req.on('timeout', () => {
190
201
  req.destroy();
191
- writeJson(
192
- rpcError({
193
- id: rpcId(mcpRequest),
194
- code: -32603,
195
- message: 'Request timeout after 30 seconds',
196
- })
202
+ if (!hasId) return; // notification: no response
203
+ process.stdout.write(
204
+ JSON.stringify({
205
+ jsonrpc: '2.0',
206
+ id: reqId,
207
+ error: { code: -32603, message: 'Request timeout after 30 seconds' },
208
+ }) + '\n'
197
209
  );
198
210
  });
199
211
 
@@ -201,6 +213,7 @@ function forwardToAPI(mcpRequest) {
201
213
  req.end();
202
214
  }
203
215
 
216
+
204
217
  function testConnection() {
205
218
  console.log('šŸ” Testing ReportDash DataStore connection...\n');
206
219
  console.log(`API URL: ${API_URL}`);
@@ -277,7 +290,7 @@ function testConnection() {
277
290
  console.log('āŒ Connection failed');
278
291
  console.log(`Status: ${res.statusCode}`);
279
292
  console.log(`Response: ${data}`);
280
- console.log('\nšŸ’” Check your API key in ReportDash DataStore app settings');
293
+ console.log('\nšŸ’” Check your API key in ReportDash DataStore > Destinations > API Access');
281
294
  }
282
295
  });
283
296
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reportdash-datastore-mcp-claude-desktop",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "ReportDash DataStore MCP server for Claude Desktop",
5
5
  "main": "index.js",
6
6
  "bin": {