@fnet/cli 0.2.7 → 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.7",
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,13 +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
- const mcpEndpoint = '/{{atom.doc.features.cli.mcp.path or 'mcp'}}';
18
+ const basePath = '{{atom.doc.features.cli.mcp.path or 'mcp'}}';
19
+ const mcpEndpoint = `/${basePath}`; // MCP protocol endpoint
15
20
  const verbose = args['cli-verbose'] || args.cli_verbose || false;
16
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
+
17
28
  // Verbose logging helper
18
29
  const log = (...args) => {
19
30
  if (verbose) {
@@ -105,9 +116,92 @@ app.get(mcpEndpoint, handleSessionRequest);
105
116
  // Handle DELETE requests for session termination
106
117
  app.delete(mcpEndpoint, handleSessionRequest);
107
118
 
119
+ {% if atom.doc.features.cli.mcp.http===true %}
120
+ // HTTP input endpoint (enabled via config: cli.mcp.http: true)
121
+ app.post(httpEndpoint, async (req, res) => {
122
+ log('HTTP input request received');
123
+ log('Request body:', JSON.stringify(req.body, null, 2));
124
+
125
+ try {
126
+ // Call the Node function directly with the request body
127
+ const result = await Node(req.body);
128
+
129
+ log('HTTP input processed successfully');
130
+ log('Result:', JSON.stringify(result, null, 2));
131
+
132
+ // Return the result as JSON
133
+ res.json(result);
134
+ } catch (error) {
135
+ log('HTTP input processing error:', error.message);
136
+
137
+ // Return error response
138
+ res.status(500).json({
139
+ error: error.message,
140
+ stack: verbose ? error.stack : undefined
141
+ });
142
+ }
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 %}
195
+
108
196
  app.listen(port, host, () => {
109
197
  console.log(`MCP server started with Streamable HTTP transport`);
110
- console.log(`Endpoint: http://${host}:${port}${mcpEndpoint}`);
198
+ console.log(`MCP endpoint: http://${host}:${port}${mcpEndpoint}`);
199
+ {% if atom.doc.features.cli.mcp.http===true %}
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 %}
111
205
  console.log(`Listening on ${host}:${port}`);
112
206
  if (verbose) {
113
207
  console.log(`Verbose logging enabled`);