toolbox-co-mcp-bridge 1.0.0 → 1.0.2

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 +40 -24
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,18 +1,43 @@
1
1
  #!/usr/bin/env node
2
2
  import EventSource from "eventsource";
3
3
  import fetch from "node-fetch";
4
+ import readline from "readline";
4
5
 
5
6
  // The hardcoded remote SSE endpoint for ToolBox Co. SaaS tools
6
7
  const sseUrl = "https://toolbox-mcp-1058072229791.us-central1.run.app/sse";
7
8
 
8
9
  const es = new EventSource(sseUrl);
9
10
  let postEndpoint = '';
11
+ const messageQueue = [];
12
+
13
+ async function sendPost(msg) {
14
+ try {
15
+ const response = await fetch(postEndpoint, {
16
+ method: 'POST',
17
+ headers: { 'Content-Type': 'application/json' },
18
+ body: msg
19
+ });
20
+ if (!response.ok) {
21
+ console.error(`HTTP Error from ToolBox server: ${response.status} ${response.statusText}`);
22
+ const text = await response.text();
23
+ console.error(`Server response body: ${text}`);
24
+ }
25
+ } catch (e) {
26
+ console.error("Failed to forward message from Claude to ToolBox:", e);
27
+ }
28
+ }
10
29
 
11
30
  // When the MCP server initializes the connection, it emits an 'endpoint' event
12
31
  // containing the specific URI we must POST messages to.
13
- es.addEventListener("endpoint", (e) => {
32
+ es.addEventListener("endpoint", async (e) => {
14
33
  try {
15
34
  postEndpoint = new URL(e.data, sseUrl).toString();
35
+
36
+ // Flush any queued messages that arrived before we got the endpoint
37
+ for (const msg of messageQueue) {
38
+ await sendPost(msg);
39
+ }
40
+ messageQueue.length = 0;
16
41
  } catch (err) {
17
42
  console.error("Failed to parse POST endpoint:", err);
18
43
  }
@@ -21,36 +46,27 @@ es.addEventListener("endpoint", (e) => {
21
46
  // Any messages received from the remote MCP server must be forwarded
22
47
  // locally to Claude Desktop via standard output (stdout).
23
48
  es.onmessage = (e) => {
24
- console.log(e.data);
49
+ process.stdout.write(e.data + '\n');
25
50
  };
26
51
 
27
52
  es.onerror = (e) => {
28
53
  console.error("SSE connection error:", e);
29
54
  };
30
55
 
31
- // Listen directly on standard input (stdin) for JSON-RPC messages
32
- // coming from the local MCP Client (Claude Desktop).
33
- process.stdin.on('data', async (data) => {
34
- if (!postEndpoint) {
35
- // Can optionally log a warning but the protocol expects JSON-RPC responses only in stdout.
36
- return;
37
- }
38
-
39
- // Tools or clients might batch messages separated by newlines
40
- const messages = data.toString().trim().split('\n');
56
+ // Use readline for perfect line-delimited stream reading, immune to TCP chunk truncation
57
+ const rl = readline.createInterface({
58
+ input: process.stdin,
59
+ output: process.stdout,
60
+ terminal: false
61
+ });
62
+
63
+ rl.on('line', async (line) => {
64
+ if (!line.trim()) return;
41
65
 
42
- for (const msg of messages) {
43
- if (!msg.trim()) continue;
44
-
45
- try {
46
- await fetch(postEndpoint, {
47
- method: 'POST',
48
- headers: { 'Content-Type': 'application/json' },
49
- body: msg
50
- });
51
- } catch (e) {
52
- console.error("Failed to forward message from Claude to ToolBox:", e);
53
- }
66
+ if (!postEndpoint) {
67
+ messageQueue.push(line);
68
+ } else {
69
+ await sendPost(line);
54
70
  }
55
71
  });
56
72
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolbox-co-mcp-bridge",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A bridge proxy to connect local STDIO-based MCP clients (like Claude Desktop) to the remote ToolBox Co. SSE endpoint.",
5
5
  "type": "module",
6
6
  "bin": {