@interopio/mcp-http 0.1.0-beta.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.
- package/dist/common/constants.d.ts +4 -0
- package/dist/factory.d.ts +2 -0
- package/dist/index.cjs +71928 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +71970 -0
- package/dist/main/schemas.d.ts +48 -0
- package/dist/main/server.d.ts +15 -0
- package/dist/shared/logger.d.ts +8 -0
- package/dist/shared/types.d.ts +16 -0
- package/mcp-http.d.ts +84 -0
- package/package.json +49 -0
- package/readme.md +613 -0
package/readme.md
ADDED
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
# io.Intelligence MCP HTTP
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Introduction](#introduction)
|
|
6
|
+
- [Installation](#installation)
|
|
7
|
+
- [Core Concepts](#core-concepts)
|
|
8
|
+
- [HTTP Transport](#http-transport)
|
|
9
|
+
- [Session Management](#session-management)
|
|
10
|
+
- [SSE vs JSON Response Modes](#sse-vs-json-response-modes)
|
|
11
|
+
- [DNS Rebinding Protection](#dns-rebinding-protection)
|
|
12
|
+
- [API Reference](#api-reference)
|
|
13
|
+
- [IoIntelMCPHttpFactory](#iointelmcphttpfactory)
|
|
14
|
+
- [Configuration Types](#configuration-types)
|
|
15
|
+
- [Configuration](#configuration)
|
|
16
|
+
- [License Key](#license-key)
|
|
17
|
+
- [Server Options](#server-options)
|
|
18
|
+
- [Transport Options](#transport-options)
|
|
19
|
+
- [MCP Core Server Configuration](#mcp-core-server-configuration)
|
|
20
|
+
- [Working Context Configuration](#working-context-configuration)
|
|
21
|
+
- [Integration Options](#integration-options)
|
|
22
|
+
- [With io.Connect Desktop](#with-ioconnect-desktop)
|
|
23
|
+
- [Standalone HTTP Server](#standalone-http-server)
|
|
24
|
+
- [Examples](#examples)
|
|
25
|
+
- [Basic HTTP Server](#basic-http-server)
|
|
26
|
+
- [Custom Port and CORS](#custom-port-and-cors)
|
|
27
|
+
- [With Session Management](#with-session-management)
|
|
28
|
+
- [With DNS Rebinding Protection](#with-dns-rebinding-protection)
|
|
29
|
+
- [Custom Server Configuration](#custom-server-configuration)
|
|
30
|
+
- [Complete io.Connect Desktop Integration](#complete-ioconnect-desktop-integration)
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Introduction
|
|
35
|
+
|
|
36
|
+
`@interopio/mcp-http` is a TypeScript library that provides HTTP transport implementation for Model Context Protocol (MCP) servers in the io.Intelligence ecosystem. It enables MCP functionality from `@interopio/mcp-core` to be delivered over HTTP, making it ideal for integration with io.Connect Desktop and other HTTP-based clients.
|
|
37
|
+
|
|
38
|
+
### Key Features
|
|
39
|
+
|
|
40
|
+
- **Express-based HTTP Server**: Built-in HTTP server with automatic middleware configuration
|
|
41
|
+
- **Session Management**: Support for multiple concurrent MCP sessions with unique session IDs
|
|
42
|
+
- **Server-Sent Events (SSE)**: Streaming responses for real-time communication
|
|
43
|
+
- **JSON Response Mode**: Optional simple request/response mode without streaming
|
|
44
|
+
- **Resumability**: Event store support for reconnection and message resumption
|
|
45
|
+
- **DNS Rebinding Protection**: Security features to prevent DNS rebinding attacks
|
|
46
|
+
- **Flexible CORS**: Configurable origin, headers, and exposed headers
|
|
47
|
+
- **Custom Middleware**: Hook for adding custom Express middleware
|
|
48
|
+
- **Multi-Instance Support**: Manage multiple MCP instances per session
|
|
49
|
+
|
|
50
|
+
### Target Audience
|
|
51
|
+
|
|
52
|
+
Developers building HTTP-based MCP servers for io.Connect Desktop or other HTTP clients who need to expose MCP tools and functionality over HTTP.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm install @interopio/mcp-http
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Requirements
|
|
63
|
+
|
|
64
|
+
- Node.js 16 or higher
|
|
65
|
+
- TypeScript 4.5 or higher
|
|
66
|
+
- Valid io.Intelligence license key
|
|
67
|
+
- io.Connect Desktop or io.Connect Browser instance
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Core Concepts
|
|
72
|
+
|
|
73
|
+
### HTTP Transport
|
|
74
|
+
|
|
75
|
+
The package uses the HTTP transport implementation from `@modelcontextprotocol/sdk`, exposing three primary endpoints:
|
|
76
|
+
|
|
77
|
+
- **GET `/mcp`**: Retrieve messages for an existing session (requires `mcp-session-id` header)
|
|
78
|
+
- **POST `/mcp`**: Send messages or initialize a new session
|
|
79
|
+
- **DELETE `/mcp`**: Close a session and clean up resources
|
|
80
|
+
|
|
81
|
+
All endpoints require a `mcp-session-id` header except for the initial initialization POST request.
|
|
82
|
+
|
|
83
|
+
### Session Management
|
|
84
|
+
|
|
85
|
+
Each MCP client connection is represented by a session with a unique session ID. Sessions are:
|
|
86
|
+
|
|
87
|
+
- **Generated**: Automatically using `randomUUID()` or via custom `sessionIdGenerator`
|
|
88
|
+
- **Tracked**: Stored internally and mapped to transport instances
|
|
89
|
+
- **Lifecycle-managed**: Created on initialization, closed on DELETE request
|
|
90
|
+
- **Multi-instance**: Each session can manage multiple MCP server instances
|
|
91
|
+
|
|
92
|
+
### SSE vs JSON Response Modes
|
|
93
|
+
|
|
94
|
+
The library supports two response modes:
|
|
95
|
+
|
|
96
|
+
**Server-Sent Events (SSE) - Default**
|
|
97
|
+
|
|
98
|
+
- Streams responses in real-time
|
|
99
|
+
- Maintains persistent connection
|
|
100
|
+
- Better for long-running operations
|
|
101
|
+
- Preferred for most use cases
|
|
102
|
+
|
|
103
|
+
**JSON Response Mode**
|
|
104
|
+
|
|
105
|
+
- Simple request/response pattern
|
|
106
|
+
- No persistent connection
|
|
107
|
+
- Useful for testing or simple scenarios
|
|
108
|
+
- Enabled via `enableJsonResponse: true`
|
|
109
|
+
|
|
110
|
+
### DNS Rebinding Protection
|
|
111
|
+
|
|
112
|
+
Security features to prevent DNS rebinding attacks:
|
|
113
|
+
|
|
114
|
+
- **Host Validation**: Whitelist allowed `Host` header values
|
|
115
|
+
- **Origin Validation**: Whitelist allowed `Origin` header values
|
|
116
|
+
- **Opt-in Security**: Must enable `enableDnsRebindingProtection` and configure allowed hosts/origins
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## API Reference
|
|
121
|
+
|
|
122
|
+
### IoIntelMCPHttpFactory
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
IoIntelMCPHttpFactory(
|
|
126
|
+
io: IOConnectDesktop.API,
|
|
127
|
+
config: IoIntelMCPHttp.Config
|
|
128
|
+
): Promise<void>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Factory function that initializes an HTTP-based MCP server.
|
|
132
|
+
|
|
133
|
+
**Parameters:**
|
|
134
|
+
|
|
135
|
+
- `io`: Initialized io.Connect Desktop API instance
|
|
136
|
+
- `config`: Configuration object (see [Configuration](#configuration))
|
|
137
|
+
|
|
138
|
+
**Returns:** Promise that resolves when server is started
|
|
139
|
+
|
|
140
|
+
**Throws:** Error if configuration is invalid or license key is invalid/expired
|
|
141
|
+
|
|
142
|
+
### Configuration Types
|
|
143
|
+
|
|
144
|
+
#### IoIntelMCPHttp.Config
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
interface Config {
|
|
148
|
+
licenseKey: string;
|
|
149
|
+
transportOptions?: HTTPTransportOptions;
|
|
150
|
+
server?: ServerOptions;
|
|
151
|
+
mcpCoreServer?: Omit<IoIntelMCPCore.McpServerConfig, "name" | "title">;
|
|
152
|
+
mcpWorkingContext?: IoIntelMCPCore.WorkingContextConfig;
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### ServerOptions
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
interface ServerOptions {
|
|
160
|
+
port?: number;
|
|
161
|
+
origin?: string | string[];
|
|
162
|
+
exposedHeaders?: string[];
|
|
163
|
+
allowedHeaders?: string[];
|
|
164
|
+
configureServer?: (app: Application) => Promise<void>;
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### HTTPTransportOptions
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
interface HTTPTransportOptions {
|
|
172
|
+
sessionIdGenerator?: (() => string) | undefined;
|
|
173
|
+
onsessioninitialized?: (sessionId: string) => void | Promise<void>;
|
|
174
|
+
onsessionclosed?: (sessionId: string) => void | Promise<void>;
|
|
175
|
+
enableJsonResponse?: boolean;
|
|
176
|
+
eventStore?: EventStore;
|
|
177
|
+
allowedHosts?: string[];
|
|
178
|
+
allowedOrigins?: string[];
|
|
179
|
+
enableDnsRebindingProtection?: boolean;
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Configuration
|
|
186
|
+
|
|
187
|
+
### License Key
|
|
188
|
+
|
|
189
|
+
A valid io.Intelligence license key is **required**:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
const config = {
|
|
193
|
+
licenseKey: "your-signed-jwt-token-here",
|
|
194
|
+
// ...
|
|
195
|
+
};
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Server Options
|
|
199
|
+
|
|
200
|
+
#### port
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
server: {
|
|
204
|
+
port: 8080; // Default: 8080
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Port number for the HTTP server (1-65535).
|
|
209
|
+
|
|
210
|
+
#### origin
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
server: {
|
|
214
|
+
origin: "*"; // Default: "*"
|
|
215
|
+
// or
|
|
216
|
+
origin: ["https://example.com", "https://app.example.com"];
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
CORS origin configuration. Can be a single string or array of allowed origins.
|
|
221
|
+
|
|
222
|
+
#### exposedHeaders
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
server: {
|
|
226
|
+
exposedHeaders: ["Mcp-Session-Id"]; // Default
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
HTTP headers exposed to clients via CORS.
|
|
231
|
+
|
|
232
|
+
#### allowedHeaders
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
server: {
|
|
236
|
+
allowedHeaders: ["Content-Type", "mcp-session-id", "mcp-protocol-version"]; // Default
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
HTTP headers allowed in requests via CORS.
|
|
241
|
+
|
|
242
|
+
#### configureServer
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
server: {
|
|
246
|
+
configureServer: async (app) => {
|
|
247
|
+
app.use(express.static("public"));
|
|
248
|
+
app.use(customMiddleware());
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Optional callback to apply custom Express middleware before routes are registered.
|
|
254
|
+
|
|
255
|
+
### Transport Options
|
|
256
|
+
|
|
257
|
+
#### sessionIdGenerator
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
transportOptions: {
|
|
261
|
+
sessionIdGenerator: () => {
|
|
262
|
+
return customSecureUUID();
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Custom function to generate session IDs. Should return globally unique and cryptographically secure strings. Return `undefined` to disable session management.
|
|
268
|
+
|
|
269
|
+
#### onsessioninitialized
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
transportOptions: {
|
|
273
|
+
onsessioninitialized: async (sessionId) => {
|
|
274
|
+
console.log(`Session ${sessionId} initialized`);
|
|
275
|
+
await registerSession(sessionId);
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Callback invoked when a new session is initialized. Useful for tracking or logging.
|
|
281
|
+
|
|
282
|
+
#### onsessionclosed
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
transportOptions: {
|
|
286
|
+
onsessionclosed: async (sessionId) => {
|
|
287
|
+
console.log(`Session ${sessionId} closed`);
|
|
288
|
+
await cleanupSession(sessionId);
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Callback invoked when a session is closed via DELETE request. Useful for cleanup.
|
|
294
|
+
|
|
295
|
+
#### enableJsonResponse
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
transportOptions: {
|
|
299
|
+
enableJsonResponse: true; // Default: false
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Enable simple JSON response mode instead of SSE streaming.
|
|
304
|
+
|
|
305
|
+
#### eventStore
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
transportOptions: {
|
|
309
|
+
eventStore: customEventStore; // Implements EventStore interface
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Optional event store for resumability support, allowing clients to reconnect and resume.
|
|
314
|
+
|
|
315
|
+
#### DNS Rebinding Protection
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
transportOptions: {
|
|
319
|
+
enableDnsRebindingProtection: true,
|
|
320
|
+
allowedHosts: ["localhost:8080", "127.0.0.1:8080"],
|
|
321
|
+
allowedOrigins: ["http://localhost:3000"]
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Enable DNS rebinding protection with whitelisted hosts and origins.
|
|
326
|
+
|
|
327
|
+
### MCP Core Server Configuration
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
mcpCoreServer: {
|
|
331
|
+
tools: {
|
|
332
|
+
system: {
|
|
333
|
+
searchApps: { enabled: true },
|
|
334
|
+
startApps: { enabled: true }
|
|
335
|
+
},
|
|
336
|
+
static: {
|
|
337
|
+
methods: [
|
|
338
|
+
// Static method tool definitions
|
|
339
|
+
]
|
|
340
|
+
},
|
|
341
|
+
dynamic: {
|
|
342
|
+
methods: { enabled: true }
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Configure MCP tools as defined in `@interopio/mcp-core`. See the [MCP Core documentation](./mcp-core.md) for complete tool configuration options.
|
|
349
|
+
|
|
350
|
+
### Working Context Configuration
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
mcpWorkingContext: {
|
|
354
|
+
factory: IoIntelWorkingContextFactory,
|
|
355
|
+
config: {
|
|
356
|
+
// Working context configuration
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Optional working context integration. See `@interopio/intel-working-context` documentation for configuration details.
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Integration Options
|
|
366
|
+
|
|
367
|
+
### With io.Connect Desktop
|
|
368
|
+
|
|
369
|
+
The preferred integration method for io.Connect Desktop is defining the HTTP server as a service application:
|
|
370
|
+
|
|
371
|
+
**Application Definition (JSON):**
|
|
372
|
+
|
|
373
|
+
```json
|
|
374
|
+
[
|
|
375
|
+
{
|
|
376
|
+
"name": "intel-mcp-server",
|
|
377
|
+
"type": "node",
|
|
378
|
+
"details": {
|
|
379
|
+
"path": "%IO_CD_USER_DATA_DIR%/mcp/index.cjs",
|
|
380
|
+
"showConsole": true,
|
|
381
|
+
"passGlueToken": true,
|
|
382
|
+
"logging": true
|
|
383
|
+
},
|
|
384
|
+
"allowLogging": true
|
|
385
|
+
}
|
|
386
|
+
]
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**Server Implementation (index.cjs):**
|
|
390
|
+
|
|
391
|
+
```javascript
|
|
392
|
+
const IoIntelMCPHttpFactory = require("@interopio/mcp-http");
|
|
393
|
+
const IODesktop = require("@interopio/desktop");
|
|
394
|
+
|
|
395
|
+
const start = async () => {
|
|
396
|
+
const desktop = await IODesktop();
|
|
397
|
+
|
|
398
|
+
await IoIntelMCPHttpFactory(desktop, {
|
|
399
|
+
licenseKey: process.env.IO_LICENSE_KEY,
|
|
400
|
+
server: {
|
|
401
|
+
port: 8989,
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
start();
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## Examples
|
|
412
|
+
|
|
413
|
+
### Basic HTTP Server
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
import IoIntelMCPHttpFactory from "@interopio/mcp-http";
|
|
417
|
+
import IODesktop from "@interopio/desktop";
|
|
418
|
+
|
|
419
|
+
const desktop = await IODesktop();
|
|
420
|
+
|
|
421
|
+
await IoIntelMCPHttpFactory(desktop, {
|
|
422
|
+
licenseKey: process.env.IO_LICENSE_KEY!,
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// Server starts on default port 8080
|
|
426
|
+
// Endpoints available at:
|
|
427
|
+
// GET http://localhost:8080/mcp
|
|
428
|
+
// POST http://localhost:8080/mcp
|
|
429
|
+
// DELETE http://localhost:8080/mcp
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Custom Port and CORS
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
await IoIntelMCPHttpFactory(desktop, {
|
|
436
|
+
licenseKey: process.env.IO_LICENSE_KEY!,
|
|
437
|
+
server: {
|
|
438
|
+
port: 9000,
|
|
439
|
+
origin: ["https://app.example.com", "https://admin.example.com"],
|
|
440
|
+
exposedHeaders: ["Mcp-Session-Id", "X-Custom-Header"],
|
|
441
|
+
allowedHeaders: [
|
|
442
|
+
"Content-Type",
|
|
443
|
+
"mcp-session-id",
|
|
444
|
+
"mcp-protocol-version",
|
|
445
|
+
"Authorization",
|
|
446
|
+
],
|
|
447
|
+
},
|
|
448
|
+
});
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### With Session Management
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
import { randomUUID } from "crypto";
|
|
455
|
+
|
|
456
|
+
const sessionRegistry = new Map();
|
|
457
|
+
|
|
458
|
+
await IoIntelMCPHttpFactory(desktop, {
|
|
459
|
+
licenseKey: process.env.IO_LICENSE_KEY!,
|
|
460
|
+
transportOptions: {
|
|
461
|
+
sessionIdGenerator: () => {
|
|
462
|
+
return `session-${randomUUID()}`;
|
|
463
|
+
},
|
|
464
|
+
onsessioninitialized: async (sessionId) => {
|
|
465
|
+
sessionRegistry.set(sessionId, {
|
|
466
|
+
createdAt: new Date(),
|
|
467
|
+
messageCount: 0,
|
|
468
|
+
});
|
|
469
|
+
console.log(`Session ${sessionId} registered`);
|
|
470
|
+
},
|
|
471
|
+
onsessionclosed: async (sessionId) => {
|
|
472
|
+
const session = sessionRegistry.get(sessionId);
|
|
473
|
+
console.log(
|
|
474
|
+
`Session ${sessionId} closed after ${session.messageCount} messages`,
|
|
475
|
+
);
|
|
476
|
+
sessionRegistry.delete(sessionId);
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
});
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### With DNS Rebinding Protection
|
|
483
|
+
|
|
484
|
+
```typescript
|
|
485
|
+
await IoIntelMCPHttpFactory(desktop, {
|
|
486
|
+
licenseKey: process.env.IO_LICENSE_KEY!,
|
|
487
|
+
server: {
|
|
488
|
+
port: 8080,
|
|
489
|
+
},
|
|
490
|
+
transportOptions: {
|
|
491
|
+
enableDnsRebindingProtection: true,
|
|
492
|
+
allowedHosts: ["localhost:8080", "127.0.0.1:8080", "mcp-server.local:8080"],
|
|
493
|
+
allowedOrigins: ["http://localhost:3000", "https://app.example.com"],
|
|
494
|
+
},
|
|
495
|
+
});
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Custom Server Configuration
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
import express from "express";
|
|
502
|
+
import helmet from "helmet";
|
|
503
|
+
import rateLimit from "express-rate-limit";
|
|
504
|
+
|
|
505
|
+
await IoIntelMCPHttpFactory(desktop, {
|
|
506
|
+
licenseKey: process.env.IO_LICENSE_KEY!,
|
|
507
|
+
server: {
|
|
508
|
+
port: 8080,
|
|
509
|
+
configureServer: async (app) => {
|
|
510
|
+
// Add security middleware
|
|
511
|
+
app.use(helmet());
|
|
512
|
+
|
|
513
|
+
// Add rate limiting
|
|
514
|
+
const limiter = rateLimit({
|
|
515
|
+
windowMs: 15 * 60 * 1000,
|
|
516
|
+
max: 100,
|
|
517
|
+
});
|
|
518
|
+
app.use(limiter);
|
|
519
|
+
|
|
520
|
+
// Serve static files
|
|
521
|
+
app.use(express.static("public"));
|
|
522
|
+
|
|
523
|
+
// Custom health check endpoint
|
|
524
|
+
app.get("/health", (req, res) => {
|
|
525
|
+
res.json({ status: "healthy" });
|
|
526
|
+
});
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
});
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### Complete io.Connect Desktop Integration
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
import IoIntelMCPHttpFactory from "@interopio/mcp-http";
|
|
536
|
+
import IODesktop from "@interopio/desktop";
|
|
537
|
+
import IOWorkspaces from "@interopio/workspaces-api";
|
|
538
|
+
import { IoIntelWorkingContextFactory } from "@interopio/intel-working-context";
|
|
539
|
+
|
|
540
|
+
const desktop = await IODesktop({
|
|
541
|
+
logger: "info",
|
|
542
|
+
libraries: [IOWorkspaces],
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
await IoIntelMCPHttpFactory(desktop, {
|
|
546
|
+
licenseKey: process.env.IO_LICENSE_KEY!,
|
|
547
|
+
server: {
|
|
548
|
+
port: 8989,
|
|
549
|
+
origin: "*",
|
|
550
|
+
},
|
|
551
|
+
transportOptions: {
|
|
552
|
+
sessionIdGenerator: () => `mcp-${Date.now()}-${Math.random()}`,
|
|
553
|
+
onsessioninitialized: (sessionId) => {
|
|
554
|
+
console.log(`MCP session ${sessionId} initialized`);
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
mcpCoreServer: {
|
|
558
|
+
tools: {
|
|
559
|
+
system: {
|
|
560
|
+
searchApps: { enabled: true },
|
|
561
|
+
searchWorkspaces: { enabled: true },
|
|
562
|
+
startApps: { enabled: true },
|
|
563
|
+
startWorkspaces: { enabled: true },
|
|
564
|
+
},
|
|
565
|
+
static: {
|
|
566
|
+
methods: [
|
|
567
|
+
{
|
|
568
|
+
availability: "constant",
|
|
569
|
+
name: "get-portfolio",
|
|
570
|
+
config: {
|
|
571
|
+
description: "Retrieves client portfolio data",
|
|
572
|
+
inputSchema: {
|
|
573
|
+
type: "object",
|
|
574
|
+
properties: {
|
|
575
|
+
clientId: { type: "string" },
|
|
576
|
+
},
|
|
577
|
+
required: ["clientId"],
|
|
578
|
+
},
|
|
579
|
+
outputSchema: {
|
|
580
|
+
type: "object",
|
|
581
|
+
properties: {
|
|
582
|
+
portfolio: { type: "object" },
|
|
583
|
+
},
|
|
584
|
+
required: ["portfolio"],
|
|
585
|
+
},
|
|
586
|
+
},
|
|
587
|
+
interop: {
|
|
588
|
+
methodName: "portfolio.get",
|
|
589
|
+
responseTimeoutMs: 5000,
|
|
590
|
+
},
|
|
591
|
+
},
|
|
592
|
+
],
|
|
593
|
+
},
|
|
594
|
+
dynamic: {
|
|
595
|
+
methods: {
|
|
596
|
+
enabled: true,
|
|
597
|
+
guard: (method) => method.name.startsWith("mcp_"),
|
|
598
|
+
},
|
|
599
|
+
},
|
|
600
|
+
},
|
|
601
|
+
},
|
|
602
|
+
mcpWorkingContext: {
|
|
603
|
+
factory: IoIntelWorkingContextFactory,
|
|
604
|
+
config: {
|
|
605
|
+
trackers: {
|
|
606
|
+
fdc3: { enabled: true },
|
|
607
|
+
},
|
|
608
|
+
},
|
|
609
|
+
},
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
console.log("MCP HTTP server started successfully");
|
|
613
|
+
```
|