npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@interopio/mcp-core

v1.2.1

Published

io.Intelligence MCP Core Library

Downloads

597

Readme

io.Intelligence MCP Core

Table of Contents


Introduction

@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.

Key Features

  • MCP Server Creation: Initialize and manage MCP server instances compliant with the MCP specification
  • System Tools: Pre-built tools for searching and starting applications and workspaces
  • Static Tools: Define tools in configuration that are automatically managed
  • Dynamic Tools: Register and unregister tools at runtime based on application state
  • Working Context Integration: Optional integration with @interopio/working-context for enhanced context management
  • Client Capability Detection: Automatically adjusts available tools based on client capabilities
  • Multi-Transport Support: Works with STDIO, HTTP, and web-based transports

Target Audience

Developers building MCP servers for io.Connect Desktop or io.Connect Browser platforms who need to expose application functionality to LLMs.


Installation

npm install @interopio/mcp-core

Requirements

  • Node.js 16 or higher
  • TypeScript 4.5 or higher
  • Valid io.Intelligence license key
  • io.Connect Desktop or io.Connect Browser instance

Core Concepts

MCP Server

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.

Tools

Tools are functions that LLMs can call to perform actions. The library supports three types:

  • System Tools: Built-in tools for searching/starting applications and workspaces
  • Static Tools: Defined in configuration, automatically registered/unregistered based on interop availability
  • Dynamic Tools: Registered at runtime using io.interop.register with MCP-specific flags

Client Capabilities

MCP clients declare capabilities such as sampling (for search operations) and elicitation (for user confirmations). The library adjusts available tools based on these capabilities:

  • Search tools require sampling capability
  • Start tools require elicitation capability
  • Working context tools are available unless client declares experimental.workingContext

Working Context Integration

Optional integration with @interopio/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.).


API Reference

IoIntelMCPCoreFactory

IoIntelMCPCoreFactory(
  io: IOConnectBrowser.API | IOConnectDesktop.API,
  config: IoIntelMCPCore.Config
): Promise<IoIntelMCPCore.API>

Factory function that initializes the MCP Core and returns an API for managing MCP instances.

Parameters:

  • io: Initialized io.Connect API instance (Browser or Desktop)
  • config: Configuration object (see Configuration)

Returns: Promise resolving to the MCP Core API

Throws: Error if license key is invalid or expired (for trial licenses)

API Methods

createMCPInstance

createMCPInstance(
  clientCapabilities: IoIntelMCPCore.ClientCapabilities
): IoIntelMCPCore.MCPCore

Creates a new MCP server instance configured with tools appropriate for the client's capabilities.

Parameters:

  • clientCapabilities: Object declaring what the client supports

Returns: Object with id (string) and instance (McpServer)

removeMCPInstance

removeMCPInstance(id: string): void

Removes an MCP instance and cleans up associated resources.

Parameters:

  • id: Unique identifier of the instance to remove

Configuration Types

IoIntelMCPCore.Config

interface Config {
  licenseKey: string;
  transport: McpTransportConfig;
  server: McpServerConfig;
  context?: WorkingContextConfig;
}

McpTransportConfig

interface McpTransportConfig {
  type: "stdio" | "http" | "web";
}

McpServerConfig

interface McpServerConfig {
  name: string;
  title?: string;
  tools?: {
    dynamic?: DynamicToolsConfig;
    static?: StaticToolsConfig;
    system?: SystemToolConfig;
  };
}

ClientCapabilities

interface ClientCapabilities {
  sampling?: object;
  elicitation?: object;
  experimental?: {
    workingContext?: boolean;
  };
  [key: string]: unknown;
}

Configuration

License Key

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.

const config = {
  licenseKey: "your-signed-jwt-token-here",
  // ...
};

License Types:

  • Trial: Must not be expired or initialization will fail
  • Paid: Will log warning if expired but continue operation

Transport Configuration

Specifies the transport type for logging adjustment:

transport: {
  type: "stdio"; // Options: "stdio", "http", "web"
}

Important: STDIO transport disables console logging to avoid interfering with MCP protocol messages.

Server Configuration

Basic Configuration

server: {
  name: "my-mcp-server",
  title: "My MCP Server"
}

Tools Configuration

server: {
  name: "my-server",
  tools: {
    system: {
      searchApps: { enabled: true },
      searchWorkspaces: { enabled: true },
      startApps: { enabled: true },
      startWorkspaces: { enabled: true }
    },
    static: {
      methods: [],
      intents: []
    },
    dynamic: {
      methods: { enabled: true }
    }
  }
}

Working Context Configuration

context: {
  factory: IoIntelWorkingContextFactory,
  config: {
    // Working context configuration
  }
}

When provided, automatically registers the io_connect_get_working_context tool.

Application and Workspace Definition Requirements

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.

Application Definition Requirements

Required Properties:

  • 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.

Optional Properties:

  • customProperties.interop: Provides detailed information about the application's interoperability features. This property follows the ApplicationInteropInfo interface and can include:
    • methods: Array of interop methods the application exposes
    • context: Context data requirements and sources
    • intents: Intents the application can handle

Example Application Definition:

{
  "name": "proposal",
  "type": "window",
  "caption": "Manages and displays client proposals with detailed financial information",
  "details": {
    "url": "http://localhost:4100?intent=my_custom_intent"
  },
  "customProperties": {
    "includeInWorkspaces": true,
    "interop": {
      "methods": [
        {
          "name": "get-proposal-data",
          "description": "Get proposal data from the proposal app",
          "inputSchema": {
            "type": "object",
            "properties": {
              "proposalId": {
                "type": "string",
                "description": "The ID of the proposal to retrieve"
              }
            },
            "required": ["proposalId"]
          },
          "outputSchema": {
            "type": "object",
            "properties": {
              "proposalId": {
                "type": "string",
                "description": "The ID of the proposal"
              },
              "clientName": {
                "type": "string",
                "description": "The name of the client"
              },
              "amount": {
                "type": "number",
                "description": "The amount of the proposal"
              },
              "status": {
                "type": "string",
                "description": "The status of the proposal"
              }
            },
            "required": ["proposalId", "clientName", "amount", "status"]
          }
        }
      ],
      "context": {
        "sources": [
          "initial-instance",
          "global",
          "channel",
          "window",
          "workspace"
        ],
        "description": "The app uses the context data to identify the proposal to display.",
        "schema": {
          "type": "object",
          "properties": {
            "proposalId": {
              "type": "string",
              "description": "The ID of the proposal"
            },
            "clientName": {
              "type": "string",
              "description": "The name of the client"
            }
          },
          "required": ["proposalId", "clientName"]
        }
      },
      "intents": [
        {
          "name": "my_custom_intent",
          "description": "Handles requests to view proposal details.",
          "contextTypes": ["fdc3.proposal"],
          "inputSchema": {
            "type": "object",
            "properties": {
              "proposalId": {
                "type": "string",
                "description": "The ID of the proposal"
              },
              "clientName": {
                "type": "string",
                "description": "The name of the client"
              }
            },
            "required": ["proposalId", "clientName"]
          },
          "outputSchema": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "description": "The status of the intent handling"
              }
            },
            "required": ["status"]
          },
          "resultType": "fdc3.intentResult",
          "customConfig": {},
          "displayName": "View Proposal Details"
        }
      ]
    }
  },
  "intents": [
    {
      "name": "my_custom_intent"
    }
  ]
}

Workspace Definition Requirements

Required Properties:

  • 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.

Optional Properties:

  • 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.

Example Workspace Definition:

{
  "name": "All Demos",
  "type": "Workspace",
  "metadata": {
    "description": "A workspace layout containing all demo applications for comprehensive product demonstration.",
    "contextSchema": {
      "type": "object",
      "properties": {
        "clientId": {
          "type": "string",
          "description": "The client identifier to load across all applications"
        },
        "portfolioId": {
          "type": "string",
          "description": "The portfolio identifier to display"
        }
      },
      "required": ["clientId"]
    }
  },
  "components": []
}

Impact on System Tools

Applications and workspaces that don't meet the required property specifications will be automatically filtered out during the search process:

  • Applications without description: Cannot be analyzed by the LLM and will not appear in search results
  • Applications with only global/channel context sources: Filtered out as they lack specific interop capabilities
  • Workspaces without metadata.description: Cannot be explained to the LLM and will be excluded from workspace searches

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.


Integration Options

Standalone Usage

Use directly with any MCP transport:

import { IoIntelMCPCoreFactory } from "@interopio/mcp-core";
import IOConnectBrowser from "@interopio/browser";

const io = await IOConnectBrowser();

const mcpApi = await IoIntelMCPCoreFactory(io, {
  licenseKey: "your-license-key",
  transport: { type: "web" },
  server: { name: "my-server" },
});

const { instance } = mcpApi.createMCPInstance({
  sampling: {},
  elicitation: {},
});

// Connect instance to your transport

With @interopio/mcp-stdio

Provides standard input/output transport for console-based communication:

import { IoIntelMCPStdioFactory } from "@interopio/mcp-stdio";

const server = await IoIntelMCPStdioFactory(io, {
  licenseKey: "your-license-key",
  server: { name: "my-server" },
});

With @interopio/mcp-http

Provides HTTP transport, preferred for io.Connect Desktop integration:

import { IoIntelMCPHttpFactory } from "@interopio/mcp-http";

const server = await IoIntelMCPHttpFactory(io, {
  licenseKey: "your-license-key",
  server: { name: "my-server" },
  http: {
    port: 3000,
  },
});

With @interopio/mcp-web

Provides web-based transport built on io.Connect Browser, preferred when frontend must be its own server:

import { IoIntelMCPWebFactory } from "@interopio/mcp-web";

const server = await IoIntelMCPWebFactory(io, {
  licenseKey: "your-license-key",
  server: { name: "my-server" },
});

Tools

System Tools

Five built-in system tools are available:

io_connect_search_applications

Discovers applications that can satisfy user intent and returns their interaction schemas.

Input:

{
  userIntent: string; // Description of what user wants to accomplish
}

Output:

{
  canSatisfyUserIntent: boolean,
  summary: string,
  nextSteps: string,
  willSatisfyUserIntentBy: {
    workspace?: { apps: ApplicationInfo[] },
    apps?: ApplicationInfo[]
  }
}

Requires: Client sampling capability

Configuration:

system: {
  searchApps: {
    enabled: true,
    overrides: {
      name: "custom_search_apps",
      description: "Custom description"
    },
    guard: (app) => app.name !== "internal-app"
  }
}

io_connect_search_workspaces

Discovers saved workspaces that satisfy user intent.

Input:

{
  userIntent: string;
}

Output:

{
  canSatisfyUserIntent: boolean,
  summary: string,
  nextSteps: string,
  willSatisfyUserIntentBy: {
    workspace?: {
      name: string,
      description: string,
      contextSchema: object
    }
  }
}

Requires: Client sampling capability, io.Connect Workspaces API available

Configuration:

system: {
  searchWorkspaces: {
    enabled: true,
    overrides: {
      name: "custom_search_workspaces"
    },
    guard: (ws) => !ws.name.startsWith("_internal")
  }
}

io_connect_start_applications

Launches applications with populated context data.

Input:

{
  apps: Array<{
    name: string;
    initialInstanceContext?: object;
    startOptions?: {
      channelName?: string;
      height?: number;
      width?: number;
      top?: number;
      left?: number;
    };
    interop?: {
      method?: { name: string; params?: object };
      windowContext?: object;
      intent?: {
        name: string;
        intentContextType?: string;
        intentContextData?: object;
      };
    };
  }>;
}

Output:

{
  apps: Array<{
    name: string;
    status: "success" | "error";
    responseData?: any;
    errorMessage?: string;
  }>;
}

Requires: Client elicitation capability

Configuration:

system: {
  startApps: {
    enabled: true,
    overrides: {
      description: "Custom start description"
    }
  }
}

io_connect_start_workspace

Creates new workspace or restores existing workspace with context.

Input:

{
  workspace:
    | { name: string, context?: object } // Restore
    | { apps: Array<...>, workspaceContext?: object } // Create
}

Output:

{
  result: {
    id: string,
    status: "success" | "error",
    errorMessage?: string,
    methodInvocationResults?: Array<{
      app: string,
      invocationResult: any
    }>
  }
}

Requires: Client elicitation capability, io.Connect Workspaces API available

io_connect_get_working_context

Retrieves current working context from io.Connect.

Input: None

Output:

{
  workingContext: Record<
    string,
    {
      description?: string;
      value: any;
    }
  >;
}

Requires: Working context configured, client does not declare experimental.workingContext

Static Tools

Static tools are defined in configuration and automatically managed by MCP Core.

Static Method Tools

static: {
  methods: [
    {
      availability: "constant", // or "variable"
      name: "my-tool-hello",
      config: {
        description: "Greets a person",
        inputSchema: {
          type: "object",
          properties: {
            name: { type: "string", description: "Person's name" },
          },
          required: ["name"],
        },
        outputSchema: {
          type: "object",
          properties: {
            greeting: { type: "string" },
          },
          required: ["greeting"],
        },
      },
      interop: {
        methodName: "my_custom_method",
        responseTimeoutMs: 5000,
        allowedApplications: ["app1", "app2"],
      },
    },
  ];
}

Availability:

  • constant: Registered at startup, never changes
  • variable: Registered/unregistered automatically based on interop availability

Interop Application:

await io.interop.register(
  {
    name: "my_custom_method",
  },
  (args) => {
    return { greeting: `Hello, ${args.name}` };
  },
);

Static Intent Tools

static: {
  intents: [
    {
      availability: "variable",
      name: "my-intent-tool",
      config: {
        description: "Handles custom intent",
        inputSchema: {
          type: "object",
          properties: {
            type: { type: "string" },
            data: { type: "object" },
          },
          required: ["type"],
        },
        outputSchema: {
          /* ... */
        },
      },
      interop: {
        intentName: "my_custom_intent",
        resolutionStrategy: "mcp", // or "io_connect"
        allowedApplications: ["handler-app"],
      },
    },
  ];
}

Resolution Strategies:

  • mcp: Prefers app handlers over instance handlers
  • io_connect: Uses io.Connect's default resolution

Interop Application:

await io.intents.register({ intent: "my_custom_intent" }, (ctx) => {
  return { result: `Processed ${ctx.data.type}` };
});

Dynamic Tools

Dynamic tools are registered at runtime and managed entirely by the application.

Registration

await io.interop.register(
  {
    name: "awesome-method",
    description: "An awesome MCP tool", // Required
    flags: {
      ioIntelMCPTool: {
        name: "io_jpm_greeting_tool",
        inputSchema: JSON.stringify({
          $schema: "https://json-schema.org/draft-07/schema",
          type: "object",
          properties: {
            name: { type: "string", description: "Person's name" },
          },
          required: ["name"],
        }),
        outputSchema: JSON.stringify({
          type: "object",
          properties: {
            greeting: { type: "string" },
          },
          required: ["greeting"],
        }),
      },
    },
  },
  (args) => {
    return { greeting: `Hello, ${args.name}` };
  },
);

Configuration Options

interface InteropMethodToolConfig {
  name: string;
  inputSchema: string; // JSON Schema as string
  outputSchema: string; // JSON Schema as string
  title?: string;
  annotations?: {
    title?: string;
    readOnlyHint?: boolean;
    destructiveHint?: boolean;
    idempotentHint?: boolean;
    openWorldHint?: boolean;
  };
  _meta?: Record<string, unknown>;
  responseTimeoutMs?: number;
}

Guard Function

Filter which methods become MCP tools:

dynamic: {
  methods: {
    enabled: true,
    guard: (method, server) => {
      return method.name.startsWith("mcp_") &&
             server.applicationName === "allowed-app";
    }
  }
}

Examples

Basic Server Setup

import { IoIntelMCPCoreFactory } from "@interopio/mcp-core";
import IOConnectBrowser from "@interopio/browser";

const io = await IOConnectBrowser();

const mcpApi = await IoIntelMCPCoreFactory(io, {
  licenseKey: process.env.IO_LICENSE_KEY!,
  transport: { type: "web" },
  server: {
    name: "basic-server",
    title: "Basic MCP Server",
  },
});

const { instance } = mcpApi.createMCPInstance({
  sampling: {},
  elicitation: {},
});

console.log("MCP server ready");

With Working Context

import { IoIntelMCPCoreFactory } from "@interopio/mcp-core";
import { IoIntelWorkingContextFactory } from "@interopio/working-context";
import IOConnectBrowser from "@interopio/browser";

const io = await IOConnectBrowser();

const mcpApi = await IoIntelMCPCoreFactory(io, {
  licenseKey: process.env.IO_LICENSE_KEY!,
  transport: { type: "web" },
  server: { name: "context-server" },
  context: {
    factory: IoIntelWorkingContextFactory,
    config: {
      trackers: {
        fdc3: { enabled: true },
      },
    },
  },
});

const { instance } = mcpApi.createMCPInstance({
  sampling: {},
  elicitation: {},
});

// io_connect_get_working_context tool is now available

Custom Static Tools

const mcpApi = await IoIntelMCPCoreFactory(io, {
  licenseKey: process.env.IO_LICENSE_KEY!,
  transport: { type: "http" },
  server: {
    name: "static-tools-server",
    tools: {
      static: {
        methods: [
          {
            availability: "constant",
            name: "get-client-portfolio",
            config: {
              description: "Retrieves portfolio for a client",
              inputSchema: {
                type: "object",
                properties: {
                  clientId: {
                    type: "string",
                    description: "Client identifier",
                  },
                },
                required: ["clientId"],
              },
              outputSchema: {
                type: "object",
                properties: {
                  portfolio: {
                    type: "object",
                    description: "Client portfolio data",
                  },
                },
                required: ["portfolio"],
              },
            },
            interop: {
              methodName: "portfolio.get",
              responseTimeoutMs: 3000,
              allowedApplications: ["portfolio-service"],
            },
          },
        ],
      },
    },
  },
});

// Register the backend method
await io.interop.register(
  {
    name: "portfolio.get",
  },
  async ({ clientId }) => {
    const portfolio = await fetchPortfolio(clientId);
    return { portfolio };
  },
);

Dynamic Tool Registration

const mcpApi = await IoIntelMCPCoreFactory(io, {
  licenseKey: process.env.IO_LICENSE_KEY!,
  transport: { type: "stdio" },
  server: {
    name: "dynamic-tools-server",
    tools: {
      dynamic: {
        methods: {
          enabled: true,
          guard: (method) => method.name.startsWith("ai_"),
        },
      },
    },
  },
});

// Register dynamic tool
await io.interop.register(
  {
    name: "ai_calculate_risk",
    description: "Calculates risk score for a portfolio",
    flags: {
      ioIntelMCPTool: {
        name: "calculate_risk",
        inputSchema: JSON.stringify({
          type: "object",
          properties: {
            portfolioId: { type: "string" },
          },
          required: ["portfolioId"],
        }),
        outputSchema: JSON.stringify({
          type: "object",
          properties: {
            riskScore: { type: "number" },
          },
          required: ["riskScore"],
        }),
      },
    },
  },
  async ({ portfolioId }) => {
    const riskScore = await calculateRisk(portfolioId);
    return { riskScore };
  },
);

// Tool is automatically available to MCP clients