@fnet/cli 0.2.8 → 0.2.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fnet/cli",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "files": [
5
5
  "dist",
6
6
  "template"
@@ -12,6 +12,9 @@ import { ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprot
12
12
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
13
13
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
14
14
  import express from "express";
15
+ {% if atom.doc.features.cli.mcp.ws===true %}
16
+ import expressWs from "express-ws";
17
+ {% endif %}
15
18
  {# crypto imported in shared section #}
16
19
 
17
20
  {% elif atom.doc.features.project.format==='cjs' %}
@@ -21,6 +24,9 @@ const { ListToolsRequestSchema, CallToolRequestSchema } = require("@modelcontext
21
24
  const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js");
22
25
  const { StreamableHTTPServerTransport } = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
23
26
  const express = require("express");
27
+ {% if atom.doc.features.cli.mcp.ws===true %}
28
+ const expressWs = require("express-ws");
29
+ {% endif %}
24
30
  {# crypto imported in shared section #}
25
31
 
26
32
  {% endif %}
@@ -7,15 +7,24 @@
7
7
 
8
8
  // Use Streamable HTTP transport (official transport as of MCP 2025-03-26)
9
9
  const app = express();
10
+ {% if atom.doc.features.cli.mcp.ws===true %}
11
+ // Enable WebSocket support
12
+ expressWs(app);
13
+ {% endif %}
10
14
  app.use(express.json());
11
15
 
12
16
  const port = args['cli-port'] || args.cli_port || 3000;
13
17
  const host = args['cli-host'] || args.cli_host || '0.0.0.0';
14
18
  const basePath = '{{atom.doc.features.cli.mcp.path or 'mcp'}}';
15
19
  const mcpEndpoint = `/${basePath}`; // MCP protocol endpoint
16
- const httpEndpoint = `/${basePath}/input`; // HTTP input endpoint
17
20
  const verbose = args['cli-verbose'] || args.cli_verbose || false;
18
21
 
22
+ // Optional endpoints (enabled via config)
23
+ const httpEnabled = {{atom.doc.features.cli.mcp.http or false}};
24
+ const wsEnabled = {{atom.doc.features.cli.mcp.ws or false}};
25
+ const httpEndpoint = `/${basePath}/input`; // HTTP input endpoint
26
+ const wsEndpoint = `/${basePath}/ws`; // WebSocket endpoint
27
+
19
28
  // Verbose logging helper
20
29
  const log = (...args) => {
21
30
  if (verbose) {
@@ -107,7 +116,8 @@ app.get(mcpEndpoint, handleSessionRequest);
107
116
  // Handle DELETE requests for session termination
108
117
  app.delete(mcpEndpoint, handleSessionRequest);
109
118
 
110
- // Handle HTTP POST requests for normal input processing (non-MCP)
119
+ {% if atom.doc.features.cli.mcp.http===true %}
120
+ // HTTP input endpoint (enabled via config: cli.mcp.http: true)
111
121
  app.post(httpEndpoint, async (req, res) => {
112
122
  log('HTTP input request received');
113
123
  log('Request body:', JSON.stringify(req.body, null, 2));
@@ -131,11 +141,67 @@ app.post(httpEndpoint, async (req, res) => {
131
141
  });
132
142
  }
133
143
  });
144
+ {% endif %}
145
+
146
+ {% if atom.doc.features.cli.mcp.ws===true %}
147
+ // WebSocket endpoint (enabled via config: cli.mcp.ws: true)
148
+ // Map to store WebSocket clients
149
+ const wsClients = new Set();
150
+
151
+ app.ws(wsEndpoint, (ws, req) => {
152
+ log('WebSocket connection established');
153
+ wsClients.add(ws);
154
+
155
+ // Handle incoming messages
156
+ ws.on('message', async (message) => {
157
+ log('WebSocket message received:', message);
158
+
159
+ try {
160
+ // Parse JSON message
161
+ const data = JSON.parse(message);
162
+
163
+ // Call the Node function
164
+ const result = await Node(data);
165
+
166
+ log('WebSocket message processed successfully');
167
+ log('Result:', JSON.stringify(result, null, 2));
168
+
169
+ // Send result back to client
170
+ ws.send(JSON.stringify(result));
171
+ } catch (error) {
172
+ log('WebSocket message processing error:', error.message);
173
+
174
+ // Send error response
175
+ ws.send(JSON.stringify({
176
+ error: error.message,
177
+ stack: verbose ? error.stack : undefined
178
+ }));
179
+ }
180
+ });
181
+
182
+ // Handle connection close
183
+ ws.on('close', () => {
184
+ log('WebSocket connection closed');
185
+ wsClients.delete(ws);
186
+ });
187
+
188
+ // Handle errors
189
+ ws.on('error', (error) => {
190
+ log('WebSocket error:', error.message);
191
+ wsClients.delete(ws);
192
+ });
193
+ });
194
+ {% endif %}
134
195
 
135
196
  app.listen(port, host, () => {
136
197
  console.log(`MCP server started with Streamable HTTP transport`);
137
198
  console.log(`MCP endpoint: http://${host}:${port}${mcpEndpoint}`);
199
+ {% if atom.doc.features.cli.mcp.http===true %}
138
200
  console.log(`HTTP endpoint: http://${host}:${port}${httpEndpoint}`);
201
+ {% endif %}
202
+ {% if atom.doc.features.cli.mcp.ws===true %}
203
+ console.log(`WebSocket endpoint: ws://${host}:${port}${wsEndpoint}`);
204
+ {% endif %}
139
205
  console.log(`Listening on ${host}:${port}`);
140
206
  if (verbose) {
141
207
  console.log(`Verbose logging enabled`);