@interopio/mcp-core 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/changelog.md +2 -0
- package/dist/mcp-core.es.js +19966 -0
- package/dist/mcp-core.es.js.map +1 -0
- package/dist/mcp-core.umd.js +19974 -0
- package/dist/mcp-core.umd.js.map +1 -0
- package/mcp-core.d.ts +148 -0
- package/package.json +51 -0
- package/readme.md +1091 -0
package/readme.md
ADDED
|
@@ -0,0 +1,1091 @@
|
|
|
1
|
+
# io.Intelligence MCP Core
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Introduction](#introduction)
|
|
6
|
+
- [Installation](#installation)
|
|
7
|
+
- [Core Concepts](#core-concepts)
|
|
8
|
+
- [MCP Server](#mcp-server)
|
|
9
|
+
- [Tools](#tools)
|
|
10
|
+
- [Client Capabilities](#client-capabilities)
|
|
11
|
+
- [Working Context Integration](#working-context-integration)
|
|
12
|
+
- [API Reference](#api-reference)
|
|
13
|
+
- [IoIntelMCPCoreFactory](#iointelmcpcorefactory)
|
|
14
|
+
- [API Methods](#api-methods)
|
|
15
|
+
- [Configuration Types](#configuration-types)
|
|
16
|
+
- [Configuration](#configuration)
|
|
17
|
+
- [License Key](#license-key)
|
|
18
|
+
- [Transport Configuration](#transport-configuration)
|
|
19
|
+
- [Server Configuration](#server-configuration)
|
|
20
|
+
- [Working Context Configuration](#working-context-configuration)
|
|
21
|
+
- [Application and Workspace Definition Requirements](#application-and-workspace-definition-requirements)
|
|
22
|
+
- [Integration Options](#integration-options)
|
|
23
|
+
- [Standalone Usage](#standalone-usage)
|
|
24
|
+
- [With @interopio/mcp-stdio](#with-interopio-mcp-stdio)
|
|
25
|
+
- [With @interopio/mcp-http](#with-interopio-mcp-http)
|
|
26
|
+
- [With @interopio/mcp-web](#with-interopio-mcp-web)
|
|
27
|
+
- [Tools](#tools-1)
|
|
28
|
+
- [System Tools](#system-tools)
|
|
29
|
+
- [Static Tools](#static-tools)
|
|
30
|
+
- [Dynamic Tools](#dynamic-tools)
|
|
31
|
+
- [Examples](#examples)
|
|
32
|
+
- [Basic Server Setup](#basic-server-setup)
|
|
33
|
+
- [With Working Context](#with-working-context)
|
|
34
|
+
- [Custom Static Tools](#custom-static-tools)
|
|
35
|
+
- [Dynamic Tool Registration](#dynamic-tool-registration)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Introduction
|
|
40
|
+
|
|
41
|
+
`@interopio/mcp-core` is a TypeScript library that provides foundational functionality for building Model Context Protocol (MCP) servers within the io.Intelligence ecosystem. It enables seamless interoperability between applications and Large Language Models (LLMs) by providing interfaces and functions to create, register, and manage MCP tools.
|
|
42
|
+
|
|
43
|
+
### Key Features
|
|
44
|
+
|
|
45
|
+
- **MCP Server Creation**: Initialize and manage MCP server instances compliant with the MCP specification
|
|
46
|
+
- **System Tools**: Pre-built tools for searching and starting applications and workspaces
|
|
47
|
+
- **Static Tools**: Define tools in configuration that are automatically managed
|
|
48
|
+
- **Dynamic Tools**: Register and unregister tools at runtime based on application state
|
|
49
|
+
- **Working Context Integration**: Optional integration with `@interopio/intel-working-context` for enhanced context management
|
|
50
|
+
- **Client Capability Detection**: Automatically adjusts available tools based on client capabilities
|
|
51
|
+
- **Multi-Transport Support**: Works with STDIO, HTTP, and web-based transports
|
|
52
|
+
|
|
53
|
+
### Target Audience
|
|
54
|
+
|
|
55
|
+
Developers building MCP servers for io.Connect Desktop or io.Connect Browser platforms who need to expose application functionality to LLMs.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install @interopio/mcp-core
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Requirements
|
|
66
|
+
|
|
67
|
+
- Node.js 16 or higher
|
|
68
|
+
- TypeScript 4.5 or higher
|
|
69
|
+
- Valid io.Intelligence license key
|
|
70
|
+
- io.Connect Desktop or io.Connect Browser instance
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Core Concepts
|
|
75
|
+
|
|
76
|
+
### MCP Server
|
|
77
|
+
|
|
78
|
+
An MCP server acts as a bridge between LLMs and io.Connect applications. The core library creates standard `McpServer` instances that can be connected to any MCP-compliant transport. Each server instance exposes tools that LLMs can invoke to interact with applications.
|
|
79
|
+
|
|
80
|
+
### Tools
|
|
81
|
+
|
|
82
|
+
Tools are functions that LLMs can call to perform actions. The library supports three types:
|
|
83
|
+
|
|
84
|
+
- **System Tools**: Built-in tools for searching/starting applications and workspaces
|
|
85
|
+
- **Static Tools**: Defined in configuration, automatically registered/unregistered based on interop availability
|
|
86
|
+
- **Dynamic Tools**: Registered at runtime using `io.interop.register` with MCP-specific flags
|
|
87
|
+
|
|
88
|
+
### Client Capabilities
|
|
89
|
+
|
|
90
|
+
MCP clients declare capabilities such as `sampling` (for search operations) and `elicitation` (for user confirmations). The library adjusts available tools based on these capabilities:
|
|
91
|
+
|
|
92
|
+
- Search tools require `sampling` capability
|
|
93
|
+
- Start tools require `elicitation` capability
|
|
94
|
+
- Working context tools are available unless client declares `experimental.workingContext`
|
|
95
|
+
|
|
96
|
+
### Working Context Integration
|
|
97
|
+
|
|
98
|
+
Optional integration with `@interopio/intel-working-context` enables the `io_connect_get_working_context` tool, allowing LLMs to retrieve the user's current business context (selected clients, portfolios, instruments, etc.).
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## API Reference
|
|
103
|
+
|
|
104
|
+
### IoIntelMCPCoreFactory
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
IoIntelMCPCoreFactory(
|
|
108
|
+
io: IOConnectBrowser.API | IOConnectDesktop.API,
|
|
109
|
+
config: IoIntelMCPCore.Config
|
|
110
|
+
): Promise<IoIntelMCPCore.API>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Factory function that initializes the MCP Core and returns an API for managing MCP instances.
|
|
114
|
+
|
|
115
|
+
**Parameters:**
|
|
116
|
+
|
|
117
|
+
- `io`: Initialized io.Connect API instance (Browser or Desktop)
|
|
118
|
+
- `config`: Configuration object (see [Configuration](#configuration))
|
|
119
|
+
|
|
120
|
+
**Returns:** Promise resolving to the MCP Core API
|
|
121
|
+
|
|
122
|
+
**Throws:** Error if license key is invalid or expired (for trial licenses)
|
|
123
|
+
|
|
124
|
+
### API Methods
|
|
125
|
+
|
|
126
|
+
#### createMCPInstance
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
createMCPInstance(
|
|
130
|
+
clientCapabilities: IoIntelMCPCore.ClientCapabilities
|
|
131
|
+
): IoIntelMCPCore.MCPCore
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Creates a new MCP server instance configured with tools appropriate for the client's capabilities.
|
|
135
|
+
|
|
136
|
+
**Parameters:**
|
|
137
|
+
|
|
138
|
+
- `clientCapabilities`: Object declaring what the client supports
|
|
139
|
+
|
|
140
|
+
**Returns:** Object with `id` (string) and `instance` (McpServer)
|
|
141
|
+
|
|
142
|
+
#### removeMCPInstance
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
removeMCPInstance(id: string): void
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Removes an MCP instance and cleans up associated resources.
|
|
149
|
+
|
|
150
|
+
**Parameters:**
|
|
151
|
+
|
|
152
|
+
- `id`: Unique identifier of the instance to remove
|
|
153
|
+
|
|
154
|
+
### Configuration Types
|
|
155
|
+
|
|
156
|
+
#### IoIntelMCPCore.Config
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
interface Config {
|
|
160
|
+
licenseKey: string;
|
|
161
|
+
transport: McpTransportConfig;
|
|
162
|
+
server: McpServerConfig;
|
|
163
|
+
context?: WorkingContextConfig;
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### McpTransportConfig
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
interface McpTransportConfig {
|
|
171
|
+
type: "stdio" | "http" | "web";
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
#### McpServerConfig
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
interface McpServerConfig {
|
|
179
|
+
name: string;
|
|
180
|
+
title?: string;
|
|
181
|
+
tools?: {
|
|
182
|
+
dynamic?: DynamicToolsConfig;
|
|
183
|
+
static?: StaticToolsConfig;
|
|
184
|
+
system?: SystemToolConfig;
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### ClientCapabilities
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
interface ClientCapabilities {
|
|
193
|
+
sampling?: object;
|
|
194
|
+
elicitation?: object;
|
|
195
|
+
experimental?: {
|
|
196
|
+
workingContext?: boolean;
|
|
197
|
+
};
|
|
198
|
+
[key: string]: unknown;
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Configuration
|
|
205
|
+
|
|
206
|
+
### License Key
|
|
207
|
+
|
|
208
|
+
A valid io.Intelligence license key is **required** to use this package. The license is a signed JWT token provided by the io.Intelligence team.
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
const config = {
|
|
212
|
+
licenseKey: "your-signed-jwt-token-here",
|
|
213
|
+
// ...
|
|
214
|
+
};
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**License Types:**
|
|
218
|
+
|
|
219
|
+
- **Trial**: Must not be expired or initialization will fail
|
|
220
|
+
- **Paid**: Will log warning if expired but continue operation
|
|
221
|
+
|
|
222
|
+
### Transport Configuration
|
|
223
|
+
|
|
224
|
+
Specifies the transport type for logging adjustment:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
transport: {
|
|
228
|
+
type: "stdio"; // Options: "stdio", "http", "web"
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Important**: STDIO transport disables console logging to avoid interfering with MCP protocol messages.
|
|
233
|
+
|
|
234
|
+
### Server Configuration
|
|
235
|
+
|
|
236
|
+
#### Basic Configuration
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
server: {
|
|
240
|
+
name: "my-mcp-server",
|
|
241
|
+
title: "My MCP Server"
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
#### Tools Configuration
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
server: {
|
|
249
|
+
name: "my-server",
|
|
250
|
+
tools: {
|
|
251
|
+
system: {
|
|
252
|
+
searchApps: { enabled: true },
|
|
253
|
+
searchWorkspaces: { enabled: true },
|
|
254
|
+
startApps: { enabled: true },
|
|
255
|
+
startWorkspaces: { enabled: true }
|
|
256
|
+
},
|
|
257
|
+
static: {
|
|
258
|
+
methods: [],
|
|
259
|
+
intents: []
|
|
260
|
+
},
|
|
261
|
+
dynamic: {
|
|
262
|
+
methods: { enabled: true }
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Working Context Configuration
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
context: {
|
|
272
|
+
factory: IoIntelWorkingContextFactory,
|
|
273
|
+
config: {
|
|
274
|
+
// Working context configuration
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
When provided, automatically registers the `io_connect_get_working_context` tool.
|
|
280
|
+
|
|
281
|
+
### Application and Workspace Definition Requirements
|
|
282
|
+
|
|
283
|
+
For the system searching tools (`io_connect_search_applications` and `io_connect_search_workspaces`) to work effectively, application and workspace definitions in io.Connect must contain specific properties that enable the LLM to understand and explain their purpose.
|
|
284
|
+
|
|
285
|
+
#### Application Definition Requirements
|
|
286
|
+
|
|
287
|
+
**Required Properties:**
|
|
288
|
+
|
|
289
|
+
- **`caption`**: A clear, descriptive explanation of what the application does. Without this property, the searching system tools cannot explain the application's functionality to the LLM, and the application will be filtered out from search results.
|
|
290
|
+
|
|
291
|
+
**Optional Properties:**
|
|
292
|
+
|
|
293
|
+
- **`customProperties.interop`**: Provides detailed information about the application's interoperability features. This property follows the `ApplicationInteropInfo` interface and can include:
|
|
294
|
+
- `methods`: Array of interop methods the application exposes
|
|
295
|
+
- `context`: Context data requirements and sources
|
|
296
|
+
- `intents`: Intents the application can handle
|
|
297
|
+
|
|
298
|
+
**Example Application Definition:**
|
|
299
|
+
|
|
300
|
+
```json
|
|
301
|
+
{
|
|
302
|
+
"name": "proposal",
|
|
303
|
+
"type": "window",
|
|
304
|
+
"caption": "Manages and displays client proposals with detailed financial information",
|
|
305
|
+
"details": {
|
|
306
|
+
"url": "http://localhost:4100?intent=my_custom_intent"
|
|
307
|
+
},
|
|
308
|
+
"customProperties": {
|
|
309
|
+
"includeInWorkspaces": true,
|
|
310
|
+
"interop": {
|
|
311
|
+
"methods": [
|
|
312
|
+
{
|
|
313
|
+
"name": "get-proposal-data",
|
|
314
|
+
"description": "Get proposal data from the proposal app",
|
|
315
|
+
"inputSchema": {
|
|
316
|
+
"type": "object",
|
|
317
|
+
"properties": {
|
|
318
|
+
"proposalId": {
|
|
319
|
+
"type": "string",
|
|
320
|
+
"description": "The ID of the proposal to retrieve"
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
"required": ["proposalId"]
|
|
324
|
+
},
|
|
325
|
+
"outputSchema": {
|
|
326
|
+
"type": "object",
|
|
327
|
+
"properties": {
|
|
328
|
+
"proposalId": {
|
|
329
|
+
"type": "string",
|
|
330
|
+
"description": "The ID of the proposal"
|
|
331
|
+
},
|
|
332
|
+
"clientName": {
|
|
333
|
+
"type": "string",
|
|
334
|
+
"description": "The name of the client"
|
|
335
|
+
},
|
|
336
|
+
"amount": {
|
|
337
|
+
"type": "number",
|
|
338
|
+
"description": "The amount of the proposal"
|
|
339
|
+
},
|
|
340
|
+
"status": {
|
|
341
|
+
"type": "string",
|
|
342
|
+
"description": "The status of the proposal"
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
"required": ["proposalId", "clientName", "amount", "status"]
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
],
|
|
349
|
+
"context": {
|
|
350
|
+
"sources": [
|
|
351
|
+
"initial-instance",
|
|
352
|
+
"global",
|
|
353
|
+
"channel",
|
|
354
|
+
"window",
|
|
355
|
+
"workspace"
|
|
356
|
+
],
|
|
357
|
+
"description": "The app uses the context data to identify the proposal to display.",
|
|
358
|
+
"schema": {
|
|
359
|
+
"type": "object",
|
|
360
|
+
"properties": {
|
|
361
|
+
"proposalId": {
|
|
362
|
+
"type": "string",
|
|
363
|
+
"description": "The ID of the proposal"
|
|
364
|
+
},
|
|
365
|
+
"clientName": {
|
|
366
|
+
"type": "string",
|
|
367
|
+
"description": "The name of the client"
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
"required": ["proposalId", "clientName"]
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
"intents": [
|
|
374
|
+
{
|
|
375
|
+
"name": "my_custom_intent",
|
|
376
|
+
"description": "Handles requests to view proposal details.",
|
|
377
|
+
"contextTypes": ["fdc3.proposal"],
|
|
378
|
+
"inputSchema": {
|
|
379
|
+
"type": "object",
|
|
380
|
+
"properties": {
|
|
381
|
+
"proposalId": {
|
|
382
|
+
"type": "string",
|
|
383
|
+
"description": "The ID of the proposal"
|
|
384
|
+
},
|
|
385
|
+
"clientName": {
|
|
386
|
+
"type": "string",
|
|
387
|
+
"description": "The name of the client"
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
"required": ["proposalId", "clientName"]
|
|
391
|
+
},
|
|
392
|
+
"outputSchema": {
|
|
393
|
+
"type": "object",
|
|
394
|
+
"properties": {
|
|
395
|
+
"status": {
|
|
396
|
+
"type": "string",
|
|
397
|
+
"description": "The status of the intent handling"
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
"required": ["status"]
|
|
401
|
+
},
|
|
402
|
+
"resultType": "fdc3.intentResult",
|
|
403
|
+
"customConfig": {},
|
|
404
|
+
"displayName": "View Proposal Details"
|
|
405
|
+
}
|
|
406
|
+
]
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
"intents": [
|
|
410
|
+
{
|
|
411
|
+
"name": "my_custom_intent"
|
|
412
|
+
}
|
|
413
|
+
]
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
#### Workspace Definition Requirements
|
|
418
|
+
|
|
419
|
+
**Required Properties:**
|
|
420
|
+
|
|
421
|
+
- **`metadata.description`**: A clear explanation of what the workspace layout contains and its purpose. Without this property, the searching system tools cannot explain the workspace's functionality to the LLM, and the workspace will be excluded from search results.
|
|
422
|
+
|
|
423
|
+
**Optional Properties:**
|
|
424
|
+
|
|
425
|
+
- **`metadata.contextSchema`**: Defines the shape of the context object that the workspace uses. This JSON Schema describes the expected structure and properties of the workspace's context data.
|
|
426
|
+
|
|
427
|
+
**Example Workspace Definition:**
|
|
428
|
+
|
|
429
|
+
```json
|
|
430
|
+
{
|
|
431
|
+
"name": "All Demos",
|
|
432
|
+
"type": "Workspace",
|
|
433
|
+
"metadata": {
|
|
434
|
+
"description": "A workspace layout containing all demo applications for comprehensive product demonstration.",
|
|
435
|
+
"contextSchema": {
|
|
436
|
+
"type": "object",
|
|
437
|
+
"properties": {
|
|
438
|
+
"clientId": {
|
|
439
|
+
"type": "string",
|
|
440
|
+
"description": "The client identifier to load across all applications"
|
|
441
|
+
},
|
|
442
|
+
"portfolioId": {
|
|
443
|
+
"type": "string",
|
|
444
|
+
"description": "The portfolio identifier to display"
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
"required": ["clientId"]
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
"components": []
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
#### Impact on System Tools
|
|
455
|
+
|
|
456
|
+
Applications and workspaces that don't meet the required property specifications will be automatically filtered out during the search process:
|
|
457
|
+
|
|
458
|
+
- **Applications without `description`**: Cannot be analyzed by the LLM and will not appear in search results
|
|
459
|
+
- **Applications with only global/channel context sources**: Filtered out as they lack specific interop capabilities
|
|
460
|
+
- **Workspaces without `metadata.description`**: Cannot be explained to the LLM and will be excluded from workspace searches
|
|
461
|
+
|
|
462
|
+
Providing optional properties like `customProperties.interop` for applications and `metadata.contextSchema` for workspaces enhances the LLM's ability to make informed decisions about which applications or workspaces best satisfy user intent.
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## Integration Options
|
|
467
|
+
|
|
468
|
+
### Standalone Usage
|
|
469
|
+
|
|
470
|
+
Use directly with any MCP transport:
|
|
471
|
+
|
|
472
|
+
```typescript
|
|
473
|
+
import { IoIntelMCPCoreFactory } from "@interopio/mcp-core";
|
|
474
|
+
import IOConnectBrowser from "@interopio/browser";
|
|
475
|
+
|
|
476
|
+
const io = await IOConnectBrowser();
|
|
477
|
+
|
|
478
|
+
const mcpApi = await IoIntelMCPCoreFactory(io, {
|
|
479
|
+
licenseKey: "your-license-key",
|
|
480
|
+
transport: { type: "web" },
|
|
481
|
+
server: { name: "my-server" },
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
const { instance } = mcpApi.createMCPInstance({
|
|
485
|
+
sampling: {},
|
|
486
|
+
elicitation: {},
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
// Connect instance to your transport
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### With @interopio/mcp-stdio
|
|
493
|
+
|
|
494
|
+
Provides standard input/output transport for console-based communication:
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
import { IoIntelMCPStdioFactory } from "@interopio/mcp-stdio";
|
|
498
|
+
|
|
499
|
+
const server = await IoIntelMCPStdioFactory(io, {
|
|
500
|
+
licenseKey: "your-license-key",
|
|
501
|
+
server: { name: "my-server" },
|
|
502
|
+
});
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### With @interopio/mcp-http
|
|
506
|
+
|
|
507
|
+
Provides HTTP transport, preferred for io.Connect Desktop integration:
|
|
508
|
+
|
|
509
|
+
```typescript
|
|
510
|
+
import { IoIntelMCPHttpFactory } from "@interopio/mcp-http";
|
|
511
|
+
|
|
512
|
+
const server = await IoIntelMCPHttpFactory(io, {
|
|
513
|
+
licenseKey: "your-license-key",
|
|
514
|
+
server: { name: "my-server" },
|
|
515
|
+
http: {
|
|
516
|
+
port: 3000,
|
|
517
|
+
},
|
|
518
|
+
});
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### With @interopio/mcp-web
|
|
522
|
+
|
|
523
|
+
Provides web-based transport built on io.Connect Browser, preferred when frontend must be its own server:
|
|
524
|
+
|
|
525
|
+
```typescript
|
|
526
|
+
import { IoIntelMCPWebFactory } from "@interopio/mcp-web";
|
|
527
|
+
|
|
528
|
+
const server = await IoIntelMCPWebFactory(io, {
|
|
529
|
+
licenseKey: "your-license-key",
|
|
530
|
+
server: { name: "my-server" },
|
|
531
|
+
});
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
## Tools
|
|
537
|
+
|
|
538
|
+
### System Tools
|
|
539
|
+
|
|
540
|
+
Five built-in system tools are available:
|
|
541
|
+
|
|
542
|
+
#### io_connect_search_applications
|
|
543
|
+
|
|
544
|
+
Discovers applications that can satisfy user intent and returns their interaction schemas.
|
|
545
|
+
|
|
546
|
+
**Input:**
|
|
547
|
+
|
|
548
|
+
```typescript
|
|
549
|
+
{
|
|
550
|
+
userIntent: string; // Description of what user wants to accomplish
|
|
551
|
+
}
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
**Output:**
|
|
555
|
+
|
|
556
|
+
```typescript
|
|
557
|
+
{
|
|
558
|
+
canSatisfyUserIntent: boolean,
|
|
559
|
+
summary: string,
|
|
560
|
+
nextSteps: string,
|
|
561
|
+
willSatisfyUserIntentBy: {
|
|
562
|
+
workspace?: { apps: ApplicationInfo[] },
|
|
563
|
+
apps?: ApplicationInfo[]
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
**Requires:** Client `sampling` capability
|
|
569
|
+
|
|
570
|
+
**Configuration:**
|
|
571
|
+
|
|
572
|
+
```typescript
|
|
573
|
+
system: {
|
|
574
|
+
searchApps: {
|
|
575
|
+
enabled: true,
|
|
576
|
+
overrides: {
|
|
577
|
+
name: "custom_search_apps",
|
|
578
|
+
description: "Custom description"
|
|
579
|
+
},
|
|
580
|
+
guard: (app) => app.name !== "internal-app"
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
#### io_connect_search_workspaces
|
|
586
|
+
|
|
587
|
+
Discovers saved workspaces that satisfy user intent.
|
|
588
|
+
|
|
589
|
+
**Input:**
|
|
590
|
+
|
|
591
|
+
```typescript
|
|
592
|
+
{
|
|
593
|
+
userIntent: string;
|
|
594
|
+
}
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
**Output:**
|
|
598
|
+
|
|
599
|
+
```typescript
|
|
600
|
+
{
|
|
601
|
+
canSatisfyUserIntent: boolean,
|
|
602
|
+
summary: string,
|
|
603
|
+
nextSteps: string,
|
|
604
|
+
willSatisfyUserIntentBy: {
|
|
605
|
+
workspace?: {
|
|
606
|
+
name: string,
|
|
607
|
+
description: string,
|
|
608
|
+
contextSchema: object
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
**Requires:** Client `sampling` capability, io.Connect Workspaces API available
|
|
615
|
+
|
|
616
|
+
**Configuration:**
|
|
617
|
+
|
|
618
|
+
```typescript
|
|
619
|
+
system: {
|
|
620
|
+
searchWorkspaces: {
|
|
621
|
+
enabled: true,
|
|
622
|
+
overrides: {
|
|
623
|
+
name: "custom_search_workspaces"
|
|
624
|
+
},
|
|
625
|
+
guard: (ws) => !ws.name.startsWith("_internal")
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
#### io_connect_start_applications
|
|
631
|
+
|
|
632
|
+
Launches applications with populated context data.
|
|
633
|
+
|
|
634
|
+
**Input:**
|
|
635
|
+
|
|
636
|
+
```typescript
|
|
637
|
+
{
|
|
638
|
+
apps: Array<{
|
|
639
|
+
name: string;
|
|
640
|
+
initialInstanceContext?: object;
|
|
641
|
+
startOptions?: {
|
|
642
|
+
channelName?: string;
|
|
643
|
+
height?: number;
|
|
644
|
+
width?: number;
|
|
645
|
+
top?: number;
|
|
646
|
+
left?: number;
|
|
647
|
+
};
|
|
648
|
+
interop?: {
|
|
649
|
+
method?: { name: string; params?: object };
|
|
650
|
+
windowContext?: object;
|
|
651
|
+
intent?: {
|
|
652
|
+
name: string;
|
|
653
|
+
intentContextType?: string;
|
|
654
|
+
intentContextData?: object;
|
|
655
|
+
};
|
|
656
|
+
};
|
|
657
|
+
}>;
|
|
658
|
+
}
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
**Output:**
|
|
662
|
+
|
|
663
|
+
```typescript
|
|
664
|
+
{
|
|
665
|
+
apps: Array<{
|
|
666
|
+
name: string;
|
|
667
|
+
status: "success" | "error";
|
|
668
|
+
responseData?: any;
|
|
669
|
+
errorMessage?: string;
|
|
670
|
+
}>;
|
|
671
|
+
}
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
**Requires:** Client `elicitation` capability
|
|
675
|
+
|
|
676
|
+
**Configuration:**
|
|
677
|
+
|
|
678
|
+
```typescript
|
|
679
|
+
system: {
|
|
680
|
+
startApps: {
|
|
681
|
+
enabled: true,
|
|
682
|
+
overrides: {
|
|
683
|
+
description: "Custom start description"
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
#### io_connect_start_workspace
|
|
690
|
+
|
|
691
|
+
Creates new workspace or restores existing workspace with context.
|
|
692
|
+
|
|
693
|
+
**Input:**
|
|
694
|
+
|
|
695
|
+
```typescript
|
|
696
|
+
{
|
|
697
|
+
workspace:
|
|
698
|
+
| { name: string, context?: object } // Restore
|
|
699
|
+
| { apps: Array<...>, workspaceContext?: object } // Create
|
|
700
|
+
}
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
**Output:**
|
|
704
|
+
|
|
705
|
+
```typescript
|
|
706
|
+
{
|
|
707
|
+
result: {
|
|
708
|
+
id: string,
|
|
709
|
+
status: "success" | "error",
|
|
710
|
+
errorMessage?: string,
|
|
711
|
+
methodInvocationResults?: Array<{
|
|
712
|
+
app: string,
|
|
713
|
+
invocationResult: any
|
|
714
|
+
}>
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
**Requires:** Client `elicitation` capability, io.Connect Workspaces API available
|
|
720
|
+
|
|
721
|
+
#### io_connect_get_working_context
|
|
722
|
+
|
|
723
|
+
Retrieves current working context from io.Connect.
|
|
724
|
+
|
|
725
|
+
**Input:** None
|
|
726
|
+
|
|
727
|
+
**Output:**
|
|
728
|
+
|
|
729
|
+
```typescript
|
|
730
|
+
{
|
|
731
|
+
workingContext: Record<
|
|
732
|
+
string,
|
|
733
|
+
{
|
|
734
|
+
description?: string;
|
|
735
|
+
value: any;
|
|
736
|
+
}
|
|
737
|
+
>;
|
|
738
|
+
}
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
**Requires:** Working context configured, client does not declare `experimental.workingContext`
|
|
742
|
+
|
|
743
|
+
### Static Tools
|
|
744
|
+
|
|
745
|
+
Static tools are defined in configuration and automatically managed by MCP Core.
|
|
746
|
+
|
|
747
|
+
#### Static Method Tools
|
|
748
|
+
|
|
749
|
+
```typescript
|
|
750
|
+
static: {
|
|
751
|
+
methods: [
|
|
752
|
+
{
|
|
753
|
+
availability: "constant", // or "variable"
|
|
754
|
+
name: "my-tool-hello",
|
|
755
|
+
config: {
|
|
756
|
+
description: "Greets a person",
|
|
757
|
+
inputSchema: {
|
|
758
|
+
type: "object",
|
|
759
|
+
properties: {
|
|
760
|
+
name: { type: "string", description: "Person's name" },
|
|
761
|
+
},
|
|
762
|
+
required: ["name"],
|
|
763
|
+
},
|
|
764
|
+
outputSchema: {
|
|
765
|
+
type: "object",
|
|
766
|
+
properties: {
|
|
767
|
+
greeting: { type: "string" },
|
|
768
|
+
},
|
|
769
|
+
required: ["greeting"],
|
|
770
|
+
},
|
|
771
|
+
},
|
|
772
|
+
interop: {
|
|
773
|
+
methodName: "my_custom_method",
|
|
774
|
+
responseTimeoutMs: 5000,
|
|
775
|
+
allowedApplications: ["app1", "app2"],
|
|
776
|
+
},
|
|
777
|
+
},
|
|
778
|
+
];
|
|
779
|
+
}
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
**Availability:**
|
|
783
|
+
|
|
784
|
+
- `constant`: Registered at startup, never changes
|
|
785
|
+
- `variable`: Registered/unregistered automatically based on interop availability
|
|
786
|
+
|
|
787
|
+
**Interop Application:**
|
|
788
|
+
|
|
789
|
+
```typescript
|
|
790
|
+
await io.interop.register(
|
|
791
|
+
{
|
|
792
|
+
name: "my_custom_method",
|
|
793
|
+
},
|
|
794
|
+
(args) => {
|
|
795
|
+
return { greeting: `Hello, ${args.name}` };
|
|
796
|
+
},
|
|
797
|
+
);
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
#### Static Intent Tools
|
|
801
|
+
|
|
802
|
+
```typescript
|
|
803
|
+
static: {
|
|
804
|
+
intents: [
|
|
805
|
+
{
|
|
806
|
+
availability: "variable",
|
|
807
|
+
name: "my-intent-tool",
|
|
808
|
+
config: {
|
|
809
|
+
description: "Handles custom intent",
|
|
810
|
+
inputSchema: {
|
|
811
|
+
type: "object",
|
|
812
|
+
properties: {
|
|
813
|
+
type: { type: "string" },
|
|
814
|
+
data: { type: "object" },
|
|
815
|
+
},
|
|
816
|
+
required: ["type"],
|
|
817
|
+
},
|
|
818
|
+
outputSchema: {
|
|
819
|
+
/* ... */
|
|
820
|
+
},
|
|
821
|
+
},
|
|
822
|
+
interop: {
|
|
823
|
+
intentName: "my_custom_intent",
|
|
824
|
+
resolutionStrategy: "mcp", // or "io_connect"
|
|
825
|
+
allowedApplications: ["handler-app"],
|
|
826
|
+
},
|
|
827
|
+
},
|
|
828
|
+
];
|
|
829
|
+
}
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
**Resolution Strategies:**
|
|
833
|
+
|
|
834
|
+
- `mcp`: Prefers app handlers over instance handlers
|
|
835
|
+
- `io_connect`: Uses io.Connect's default resolution
|
|
836
|
+
|
|
837
|
+
**Interop Application:**
|
|
838
|
+
|
|
839
|
+
```typescript
|
|
840
|
+
await io.intents.register({ intent: "my_custom_intent" }, (ctx) => {
|
|
841
|
+
return { result: `Processed ${ctx.data.type}` };
|
|
842
|
+
});
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
### Dynamic Tools
|
|
846
|
+
|
|
847
|
+
Dynamic tools are registered at runtime and managed entirely by the application.
|
|
848
|
+
|
|
849
|
+
#### Registration
|
|
850
|
+
|
|
851
|
+
```typescript
|
|
852
|
+
await io.interop.register(
|
|
853
|
+
{
|
|
854
|
+
name: "awesome-method",
|
|
855
|
+
description: "An awesome MCP tool", // Required
|
|
856
|
+
flags: {
|
|
857
|
+
ioIntelMCPTool: {
|
|
858
|
+
name: "io_jpm_greeting_tool",
|
|
859
|
+
inputSchema: JSON.stringify({
|
|
860
|
+
$schema: "https://json-schema.org/draft-07/schema",
|
|
861
|
+
type: "object",
|
|
862
|
+
properties: {
|
|
863
|
+
name: { type: "string", description: "Person's name" },
|
|
864
|
+
},
|
|
865
|
+
required: ["name"],
|
|
866
|
+
}),
|
|
867
|
+
outputSchema: JSON.stringify({
|
|
868
|
+
type: "object",
|
|
869
|
+
properties: {
|
|
870
|
+
greeting: { type: "string" },
|
|
871
|
+
},
|
|
872
|
+
required: ["greeting"],
|
|
873
|
+
}),
|
|
874
|
+
},
|
|
875
|
+
},
|
|
876
|
+
},
|
|
877
|
+
(args) => {
|
|
878
|
+
return { greeting: `Hello, ${args.name}` };
|
|
879
|
+
},
|
|
880
|
+
);
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
#### Configuration Options
|
|
884
|
+
|
|
885
|
+
```typescript
|
|
886
|
+
interface InteropMethodToolConfig {
|
|
887
|
+
name: string;
|
|
888
|
+
inputSchema: string; // JSON Schema as string
|
|
889
|
+
outputSchema: string; // JSON Schema as string
|
|
890
|
+
title?: string;
|
|
891
|
+
annotations?: {
|
|
892
|
+
title?: string;
|
|
893
|
+
readOnlyHint?: boolean;
|
|
894
|
+
destructiveHint?: boolean;
|
|
895
|
+
idempotentHint?: boolean;
|
|
896
|
+
openWorldHint?: boolean;
|
|
897
|
+
};
|
|
898
|
+
_meta?: Record<string, unknown>;
|
|
899
|
+
responseTimeoutMs?: number;
|
|
900
|
+
}
|
|
901
|
+
```
|
|
902
|
+
|
|
903
|
+
#### Guard Function
|
|
904
|
+
|
|
905
|
+
Filter which methods become MCP tools:
|
|
906
|
+
|
|
907
|
+
```typescript
|
|
908
|
+
dynamic: {
|
|
909
|
+
methods: {
|
|
910
|
+
enabled: true,
|
|
911
|
+
guard: (method, server) => {
|
|
912
|
+
return method.name.startsWith("mcp_") &&
|
|
913
|
+
server.applicationName === "allowed-app";
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
```
|
|
918
|
+
|
|
919
|
+
---
|
|
920
|
+
|
|
921
|
+
## Examples
|
|
922
|
+
|
|
923
|
+
### Basic Server Setup
|
|
924
|
+
|
|
925
|
+
```typescript
|
|
926
|
+
import { IoIntelMCPCoreFactory } from "@interopio/mcp-core";
|
|
927
|
+
import IOConnectBrowser from "@interopio/browser";
|
|
928
|
+
|
|
929
|
+
const io = await IOConnectBrowser();
|
|
930
|
+
|
|
931
|
+
const mcpApi = await IoIntelMCPCoreFactory(io, {
|
|
932
|
+
licenseKey: process.env.IO_LICENSE_KEY!,
|
|
933
|
+
transport: { type: "web" },
|
|
934
|
+
server: {
|
|
935
|
+
name: "basic-server",
|
|
936
|
+
title: "Basic MCP Server",
|
|
937
|
+
},
|
|
938
|
+
});
|
|
939
|
+
|
|
940
|
+
const { instance } = mcpApi.createMCPInstance({
|
|
941
|
+
sampling: {},
|
|
942
|
+
elicitation: {},
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
console.log("MCP server ready");
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
### With Working Context
|
|
949
|
+
|
|
950
|
+
```typescript
|
|
951
|
+
import { IoIntelMCPCoreFactory } from "@interopio/mcp-core";
|
|
952
|
+
import { IoIntelWorkingContextFactory } from "@interopio/intel-working-context";
|
|
953
|
+
import IOConnectBrowser from "@interopio/browser";
|
|
954
|
+
|
|
955
|
+
const io = await IOConnectBrowser();
|
|
956
|
+
|
|
957
|
+
const mcpApi = await IoIntelMCPCoreFactory(io, {
|
|
958
|
+
licenseKey: process.env.IO_LICENSE_KEY!,
|
|
959
|
+
transport: { type: "web" },
|
|
960
|
+
server: { name: "context-server" },
|
|
961
|
+
context: {
|
|
962
|
+
factory: IoIntelWorkingContextFactory,
|
|
963
|
+
config: {
|
|
964
|
+
trackers: {
|
|
965
|
+
fdc3: { enabled: true },
|
|
966
|
+
},
|
|
967
|
+
},
|
|
968
|
+
},
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
const { instance } = mcpApi.createMCPInstance({
|
|
972
|
+
sampling: {},
|
|
973
|
+
elicitation: {},
|
|
974
|
+
});
|
|
975
|
+
|
|
976
|
+
// io_connect_get_working_context tool is now available
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
### Custom Static Tools
|
|
980
|
+
|
|
981
|
+
```typescript
|
|
982
|
+
const mcpApi = await IoIntelMCPCoreFactory(io, {
|
|
983
|
+
licenseKey: process.env.IO_LICENSE_KEY!,
|
|
984
|
+
transport: { type: "http" },
|
|
985
|
+
server: {
|
|
986
|
+
name: "static-tools-server",
|
|
987
|
+
tools: {
|
|
988
|
+
static: {
|
|
989
|
+
methods: [
|
|
990
|
+
{
|
|
991
|
+
availability: "constant",
|
|
992
|
+
name: "get-client-portfolio",
|
|
993
|
+
config: {
|
|
994
|
+
description: "Retrieves portfolio for a client",
|
|
995
|
+
inputSchema: {
|
|
996
|
+
type: "object",
|
|
997
|
+
properties: {
|
|
998
|
+
clientId: {
|
|
999
|
+
type: "string",
|
|
1000
|
+
description: "Client identifier",
|
|
1001
|
+
},
|
|
1002
|
+
},
|
|
1003
|
+
required: ["clientId"],
|
|
1004
|
+
},
|
|
1005
|
+
outputSchema: {
|
|
1006
|
+
type: "object",
|
|
1007
|
+
properties: {
|
|
1008
|
+
portfolio: {
|
|
1009
|
+
type: "object",
|
|
1010
|
+
description: "Client portfolio data",
|
|
1011
|
+
},
|
|
1012
|
+
},
|
|
1013
|
+
required: ["portfolio"],
|
|
1014
|
+
},
|
|
1015
|
+
},
|
|
1016
|
+
interop: {
|
|
1017
|
+
methodName: "portfolio.get",
|
|
1018
|
+
responseTimeoutMs: 3000,
|
|
1019
|
+
allowedApplications: ["portfolio-service"],
|
|
1020
|
+
},
|
|
1021
|
+
},
|
|
1022
|
+
],
|
|
1023
|
+
},
|
|
1024
|
+
},
|
|
1025
|
+
},
|
|
1026
|
+
});
|
|
1027
|
+
|
|
1028
|
+
// Register the backend method
|
|
1029
|
+
await io.interop.register(
|
|
1030
|
+
{
|
|
1031
|
+
name: "portfolio.get",
|
|
1032
|
+
},
|
|
1033
|
+
async ({ clientId }) => {
|
|
1034
|
+
const portfolio = await fetchPortfolio(clientId);
|
|
1035
|
+
return { portfolio };
|
|
1036
|
+
},
|
|
1037
|
+
);
|
|
1038
|
+
```
|
|
1039
|
+
|
|
1040
|
+
### Dynamic Tool Registration
|
|
1041
|
+
|
|
1042
|
+
```typescript
|
|
1043
|
+
const mcpApi = await IoIntelMCPCoreFactory(io, {
|
|
1044
|
+
licenseKey: process.env.IO_LICENSE_KEY!,
|
|
1045
|
+
transport: { type: "stdio" },
|
|
1046
|
+
server: {
|
|
1047
|
+
name: "dynamic-tools-server",
|
|
1048
|
+
tools: {
|
|
1049
|
+
dynamic: {
|
|
1050
|
+
methods: {
|
|
1051
|
+
enabled: true,
|
|
1052
|
+
guard: (method) => method.name.startsWith("ai_"),
|
|
1053
|
+
},
|
|
1054
|
+
},
|
|
1055
|
+
},
|
|
1056
|
+
},
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1059
|
+
// Register dynamic tool
|
|
1060
|
+
await io.interop.register(
|
|
1061
|
+
{
|
|
1062
|
+
name: "ai_calculate_risk",
|
|
1063
|
+
description: "Calculates risk score for a portfolio",
|
|
1064
|
+
flags: {
|
|
1065
|
+
ioIntelMCPTool: {
|
|
1066
|
+
name: "calculate_risk",
|
|
1067
|
+
inputSchema: JSON.stringify({
|
|
1068
|
+
type: "object",
|
|
1069
|
+
properties: {
|
|
1070
|
+
portfolioId: { type: "string" },
|
|
1071
|
+
},
|
|
1072
|
+
required: ["portfolioId"],
|
|
1073
|
+
}),
|
|
1074
|
+
outputSchema: JSON.stringify({
|
|
1075
|
+
type: "object",
|
|
1076
|
+
properties: {
|
|
1077
|
+
riskScore: { type: "number" },
|
|
1078
|
+
},
|
|
1079
|
+
required: ["riskScore"],
|
|
1080
|
+
}),
|
|
1081
|
+
},
|
|
1082
|
+
},
|
|
1083
|
+
},
|
|
1084
|
+
async ({ portfolioId }) => {
|
|
1085
|
+
const riskScore = await calculateRisk(portfolioId);
|
|
1086
|
+
return { riskScore };
|
|
1087
|
+
},
|
|
1088
|
+
);
|
|
1089
|
+
|
|
1090
|
+
// Tool is automatically available to MCP clients
|
|
1091
|
+
```
|