machine-bridge-mcp 0.8.1 → 0.9.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.
@@ -3,7 +3,7 @@ import toolCatalog from "../shared/tool-catalog.json";
3
3
  import serverMetadata from "../shared/server-metadata.json";
4
4
 
5
5
  const SERVER_NAME = String(serverMetadata.name);
6
- const SERVER_VERSION = "0.8.1";
6
+ const SERVER_VERSION = "0.9.0";
7
7
  const MCP_PROTOCOL_VERSION = String(serverMetadata.protocolVersion);
8
8
  const MCP_SUPPORTED_PROTOCOL_VERSIONS = serverMetadata.supportedProtocolVersions.map((value) => String(value));
9
9
  const JSONRPC_VERSION = "2.0";
@@ -217,13 +217,18 @@ export class BridgeRoom extends DurableObject<BridgeEnv> {
217
217
  try { ws.close(1007, "invalid UTF-8"); } catch {}
218
218
  return;
219
219
  }
220
- let body: Record<string, unknown>;
220
+ let parsed: unknown;
221
221
  try {
222
- body = JSON.parse(text) as Record<string, unknown>;
222
+ parsed = JSON.parse(text);
223
223
  } catch {
224
- ws.send(JSON.stringify({ type: "error", error: "invalid_json" }));
224
+ rejectDaemonMessage(ws, "invalid_json", 1007, "invalid JSON");
225
+ return;
226
+ }
227
+ if (!isObjectRecord(parsed)) {
228
+ rejectDaemonMessage(ws, "invalid_message", 1002, "daemon message must be an object");
225
229
  return;
226
230
  }
231
+ const body = parsed;
227
232
 
228
233
  const socketAttachment = this.socketAttachment(ws);
229
234
  if (!socketAttachment) {
@@ -237,6 +242,10 @@ export class BridgeRoom extends DurableObject<BridgeEnv> {
237
242
  }
238
243
 
239
244
  if (body.type === "hello") {
245
+ if (socketAttachment.role === "daemon") {
246
+ rejectDaemonMessage(ws, "duplicate_hello", 1002, "duplicate daemon hello");
247
+ return;
248
+ }
240
249
  const previousDaemons = this.daemonSockets().filter((socket) => socket !== ws);
241
250
  if (socketAttachment.role === "candidate") {
242
251
  if (!isFreshDaemonCandidate(socketAttachment.connectedAt)) {
@@ -280,7 +289,7 @@ export class BridgeRoom extends DurableObject<BridgeEnv> {
280
289
  }
281
290
 
282
291
  if (body.type !== "tool_result" || typeof body.id !== "string") {
283
- ws.send(JSON.stringify({ type: "error", error: "unknown_message_type" }));
292
+ rejectDaemonMessage(ws, "unknown_message_type", 1002, "unknown daemon message type");
284
293
  return;
285
294
  }
286
295
 
@@ -912,6 +921,15 @@ export default {
912
921
  },
913
922
  } satisfies ExportedHandler<BridgeEnv>;
914
923
 
924
+ function isObjectRecord(value: unknown): value is Record<string, unknown> {
925
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
926
+ }
927
+
928
+ function rejectDaemonMessage(ws: WebSocket, error: string, closeCode: number, closeReason: string): void {
929
+ try { ws.send(JSON.stringify({ type: "error", error })); } catch {}
930
+ try { ws.close(closeCode, closeReason); } catch {}
931
+ }
932
+
915
933
  function isJsonRpcRequest(value: unknown): value is JsonRpcRequest {
916
934
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
917
935
  const candidate = value as Record<string, unknown>;
package/tsconfig.json CHANGED
@@ -9,6 +9,8 @@
9
9
  ],
10
10
  "strict": true,
11
11
  "noEmit": true,
12
+ "noUnusedLocals": true,
13
+ "noUnusedParameters": true,
12
14
  "skipLibCheck": true,
13
15
  "forceConsistentCasingInFileNames": true,
14
16
  "resolveJsonModule": true