@fnet/cli 0.119.0 → 0.119.1

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.119.0",
3
+ "version": "0.119.1",
4
4
  "files": [
5
5
  "dist",
6
6
  "template"
@@ -72,33 +72,86 @@
72
72
  // Use stdio transport
73
73
  transport = new StdioServerTransport();
74
74
  } else if (transportType === 'http') {
75
- // Use Streamable HTTP transport (modern HTTP transport)
75
+ // Use Streamable HTTP transport (official transport as of MCP 2025-03-26)
76
76
  const app = express();
77
77
  app.use(express.json());
78
78
 
79
79
  const port = args['cli-port'] || args.cli_port || 3000;
80
- const httpServer = app.listen(port, () => {
81
- console.log(`MCP server started with Streamable HTTP transport on port ${port}`);
80
+ const host = args['cli-host'] || args.cli_host || 'localhost';
81
+ const mcpEndpoint = '/mcp';
82
+
83
+ // Security: Validate Origin header to prevent DNS rebinding attacks
84
+ app.use((req, res, next) => {
85
+ const origin = req.get('origin');
86
+ if (origin && host === 'localhost') {
87
+ const originUrl = new URL(origin);
88
+ if (originUrl.hostname !== 'localhost' && originUrl.hostname !== '127.0.0.1') {
89
+ return res.status(403).json({ error: 'Forbidden: Invalid origin' });
90
+ }
91
+ }
92
+ next();
82
93
  });
83
94
 
95
+ // Middleware to check session ID (except for initialization)
96
+ const checkSessionId = (req, res, next) => {
97
+ // Skip session check for initialization requests
98
+ if (req.method === 'POST' && req.body) {
99
+ const body = req.body;
100
+ // Check if this is an initialization request
101
+ if (body.method === 'initialize' ||
102
+ (Array.isArray(body) && body.some(item => item.method === 'initialize'))) {
103
+ return next();
104
+ }
105
+ }
106
+
107
+ // For non-initialization requests, require session ID
108
+ const sessionId = req.get('Mcp-Session-Id');
109
+ if (!sessionId) {
110
+ return res.status(400).json({
111
+ jsonrpc: '2.0',
112
+ error: {
113
+ code: -32000,
114
+ message: 'Bad Request: Mcp-Session-Id header is required'
115
+ },
116
+ id: null
117
+ });
118
+ }
119
+ next();
120
+ };
121
+
122
+ app.use(mcpEndpoint, checkSessionId);
123
+
84
124
  transport = new StreamableHTTPServerTransport({
85
- sessionIdGenerator: () => Math.random().toString(36).substring(2, 15),
125
+ sessionIdGenerator: () => {
126
+ // Generate cryptographically secure session ID
127
+ return require('crypto').randomBytes(16).toString('hex');
128
+ },
86
129
  });
87
130
 
88
- // Handle POST requests for client-to-server communication
89
- app.post('/mcp', async (req, res) => {
131
+ // Handle POST requests for client-to-server messages
132
+ app.post(mcpEndpoint, async (req, res) => {
90
133
  await transport.handleRequest(req, res, req.body);
91
134
  });
92
135
 
93
- // Handle GET requests for server-to-client notifications via SSE
94
- app.get('/mcp', async (req, res) => {
136
+ // Handle GET requests for server-to-client SSE stream
137
+ app.get(mcpEndpoint, async (req, res) => {
95
138
  await transport.handleRequest(req, res);
96
139
  });
97
140
 
98
141
  // Handle DELETE requests for session termination
99
- app.delete('/mcp', async (req, res) => {
142
+ app.delete(mcpEndpoint, async (req, res) => {
100
143
  await transport.handleRequest(req, res);
101
144
  });
145
+
146
+ const httpServer = app.listen(port, host, () => {
147
+ console.log(`MCP server started with Streamable HTTP transport`);
148
+ console.log(`Endpoint: http://${host}:${port}${mcpEndpoint}`);
149
+ console.log(`Listening on ${host}:${port}`);
150
+ });
151
+
152
+ // Connect transport to server
153
+ await server.connect(transport);
154
+ return;
102
155
  } else {
103
156
  console.error(`Unknown MCP transport type: ${transportType}`);
104
157
  console.error(`Supported types: stdio, http`);