@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/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
+ ```