Skip to main content

Examples

This page provides complete, runnable code examples demonstrating how to use @interopio/mcp-core in different scenarios. Each example includes all necessary imports and configuration to help you get started quickly.

Basic Server Setup

This example demonstrates the minimal setup required to create an MCP server with default system tools enabled.

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

// Initialize io.Connect
const io = await IOConnectBrowser();

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

// Create an MCP instance with client capabilities
const { instance } = mcpApi.createMCPInstance({
sampling: {}, // Enables search tools
elicitation: {}, // Enables start tools
});

console.log("MCP server ready with default system tools");

This basic setup automatically provides the following system tools:

  • io_connect_search_applications - Search for applications that satisfy user intent
  • io_connect_search_workspaces - Search for workspace layouts
  • io_connect_start_applications - Launch applications with context
  • io_connect_start_workspace - Create or restore workspaces

With Working Context

This example shows how to integrate the Working Context feature, which enables the io_connect_get_working_context tool for retrieving the user's current business context.

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

// Initialize io.Connect
const io = await IOConnectBrowser();

// Create MCP Core API with working context integration
const mcpApi = await IoIntelMCPCoreFactory(io, {
licenseKey: process.env.IO_LICENSE_KEY!,
transport: { type: "web" },
server: {
name: "context-server",
title: "MCP Server with Working Context"
},
context: {
factory: IoIntelWorkingContextFactory,
config: {
schema: {
clientId: {
type: "string",
source: {
context: {
location: { workspace: { target: "my" } },
path: "clientId",
},
},
},
userId: {
type: "string",
source: {
context: {
location: { global: { names: ["UserSession"] } },
path: "user.id",
},
},
},
},
},
},
});

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

console.log("MCP server ready with working context tool");
// The io_connect_get_working_context tool is now available to LLMs

The working context tool allows LLMs to retrieve information about:

  • Currently selected clients, portfolios, or instruments
  • Active workspace or global context values
  • Business context collected through the configured schema
  • Application-specific context tracked by your io.Connect environment

Custom Static Tools

This example demonstrates how to define static tools that are automatically registered and managed based on the availability of their backing interop methods.

import { IoIntelMCPCoreFactory } from "@interopio/mcp-core";
import IOConnectDesktop from "@interopio/desktop";

// Initialize io.Connect
const io = await IOConnectDesktop();

// Create MCP Core API with custom static tools
const mcpApi = await IoIntelMCPCoreFactory(io, {
licenseKey: process.env.IO_LICENSE_KEY!,
transport: { type: "http" },
server: {
name: "static-tools-server",
title: "MCP Server with Static Tools",
tools: {
static: {
methods: [
{
// Tool will always be available
availability: "constant",
name: "get-client-portfolio",
config: {
description: "Retrieves portfolio information for a specific client",
inputSchema: {
type: "object",
properties: {
clientId: {
type: "string",
description: "Unique identifier for the client",
},
},
required: ["clientId"],
},
outputSchema: {
type: "object",
properties: {
portfolio: {
type: "object",
description: "Client portfolio data including holdings and performance",
},
},
required: ["portfolio"],
},
},
interop: {
methodName: "portfolio.get",
responseTimeoutMs: 3000,
// Only accept responses from specific applications
allowedApplications: ["portfolio-service"],
},
},
{
// Tool availability tracks interop method availability
availability: "variable",
name: "update-client-risk-profile",
config: {
description: "Updates the risk profile for a client",
inputSchema: {
type: "object",
properties: {
clientId: { type: "string" },
riskLevel: {
type: "string",
enum: ["low", "medium", "high"],
description: "Client risk tolerance level",
},
},
required: ["clientId", "riskLevel"],
},
outputSchema: {
type: "object",
properties: {
success: { type: "boolean" },
updatedProfile: { type: "object" },
},
required: ["success"],
},
},
interop: {
methodName: "client.risk.update",
responseTimeoutMs: 5000,
},
},
],
},
},
},
});

// Register the backing interop methods in your application
await io.interop.register(
{
name: "portfolio.get",
},
async ({ clientId }) => {
// Fetch portfolio data from your backend
const portfolio = await fetchPortfolioData(clientId);
return { portfolio };
}
);

await io.interop.register(
{
name: "client.risk.update",
},
async ({ clientId, riskLevel }) => {
// Update client risk profile
const result = await updateRiskProfile(clientId, riskLevel);
return {
success: result.success,
updatedProfile: result.profile,
};
}
);

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

console.log("MCP server ready with static tools");

Static tools with availability: "variable" are automatically:

  • Registered when the backing interop method becomes available
  • Unregistered when the backing interop method is removed
  • Monitored for changes across all MCP instances

Dynamic Tool Registration

This example shows how to register tools dynamically at runtime using the ioIntelMCPTool flag in interop method registration. Dynamic tools give you full control over when tools become available.

import { IoIntelMCPCoreFactory } from "@interopio/mcp-core";
import IOConnectDesktop from "@interopio/desktop";

// Initialize io.Connect
const io = await IOConnectDesktop();

// Create MCP Core API with dynamic tools enabled
const mcpApi = await IoIntelMCPCoreFactory(io, {
licenseKey: process.env.IO_LICENSE_KEY!,
transport: { type: "stdio" },
server: {
name: "dynamic-tools-server",
title: "MCP Server with Dynamic Tools",
tools: {
dynamic: {
methods: {
enabled: true,
// Optional guard function to filter which methods become tools
guard: (method, server) => {
// Only register methods that start with "ai_"
return method.name.startsWith("ai_");
},
},
},
},
},
});

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

// Register a dynamic tool with the ioIntelMCPTool flag
await io.interop.register(
{
name: "ai_calculate_risk",
description: "Calculates risk score for a portfolio based on current market conditions",
flags: {
ioIntelMCPTool: {
name: "calculate_risk",
inputSchema: JSON.stringify({
type: "object",
properties: {
portfolioId: {
type: "string",
description: "Identifier of the portfolio to analyze",
},
includeForecasts: {
type: "boolean",
description: "Whether to include forward-looking risk forecasts",
},
},
required: ["portfolioId"],
}),
outputSchema: JSON.stringify({
type: "object",
properties: {
riskScore: {
type: "number",
description: "Overall risk score from 0 (low) to 100 (high)",
},
breakdown: {
type: "object",
description: "Detailed risk breakdown by category",
},
},
required: ["riskScore"],
}),
responseTimeoutMs: 10000,
},
},
},
async ({ portfolioId, includeForecasts }) => {
// Perform risk calculation
const riskScore = await calculateRiskScore(portfolioId, includeForecasts);
const breakdown = await getRiskBreakdown(portfolioId);

return {
riskScore,
breakdown,
};
}
);

// Register another dynamic tool
await io.interop.register(
{
name: "ai_generate_trade_ideas",
description: "Generates trade ideas based on client portfolio and market conditions",
flags: {
ioIntelMCPTool: {
name: "generate_trade_ideas",
inputSchema: JSON.stringify({
type: "object",
properties: {
clientId: { type: "string" },
maxIdeas: {
type: "number",
description: "Maximum number of trade ideas to generate",
default: 5,
},
},
required: ["clientId"],
}),
outputSchema: JSON.stringify({
type: "object",
properties: {
ideas: {
type: "array",
items: {
type: "object",
properties: {
symbol: { type: "string" },
action: { type: "string", enum: ["buy", "sell"] },
rationale: { type: "string" },
expectedReturn: { type: "number" },
},
},
},
},
required: ["ideas"],
}),
annotations: {
title: "Trade Idea Generator",
// Hints for LLM behavior
readOnlyHint: false,
destructiveHint: false,
idempotentHint: true,
},
},
},
},
async ({ clientId, maxIdeas = 5 }) => {
// Generate trade ideas using AI/ML model
const ideas = await generateTradeIdeas(clientId, maxIdeas);
return { ideas };
}
);

console.log("MCP server ready with dynamic tools");
// Tools are automatically available to LLMs as soon as they're registered

Dynamic tools are ideal for:

  • Tools that depend on runtime application state
  • Tools that should only be available under certain conditions
  • Tools that need to be registered/unregistered frequently
  • Tools with complex availability logic that goes beyond simple interop method presence

Combining Multiple Tool Types

This example demonstrates a complete setup using all tool types together: system tools, static tools, and dynamic tools.

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

const io = await IOConnectDesktop();

const mcpApi = await IoIntelMCPCoreFactory(io, {
licenseKey: process.env.IO_LICENSE_KEY!,
transport: { type: "http" },
server: {
name: "comprehensive-server",
title: "Comprehensive MCP Server",
tools: {
// System tools with custom configuration
system: {
searchApps: {
enabled: true,
// Filter applications shown to LLM
guard: (app) => {
return !app.name.startsWith("_internal");
},
},
startApps: { enabled: true },
searchWorkspaces: { enabled: true },
startWorkspaces: { enabled: true },
},
// Static tools for stable functionality
static: {
methods: [
{
availability: "constant",
name: "get-market-data",
config: {
description: "Retrieves current market data for a symbol",
inputSchema: {
type: "object",
properties: {
symbol: { type: "string" },
},
required: ["symbol"],
},
outputSchema: {
type: "object",
properties: {
price: { type: "number" },
volume: { type: "number" },
},
required: ["price"],
},
},
interop: {
methodName: "market.data.get",
},
},
],
},
// Dynamic tools for runtime flexibility
dynamic: {
methods: {
enabled: true,
guard: (method) => method.name.startsWith("ai_"),
},
},
},
},
// Working context for user context awareness
context: {
factory: IoIntelWorkingContextFactory,
config: {
schema: {
instrument: {
type: "object",
source: {
context: {
location: { workspace: { target: "my" } },
path: "instrument",
},
},
},
},
},
},
});

// Register static method
await io.interop.register(
{ name: "market.data.get" },
async ({ symbol }) => {
const data = await fetchMarketData(symbol);
return { price: data.price, volume: data.volume };
}
);

// Register dynamic tool
await io.interop.register(
{
name: "ai_analyze_sentiment",
description: "Analyzes market sentiment for a security",
flags: {
ioIntelMCPTool: {
name: "analyze_sentiment",
inputSchema: JSON.stringify({
type: "object",
properties: {
symbol: { type: "string" },
},
required: ["symbol"],
}),
outputSchema: JSON.stringify({
type: "object",
properties: {
sentiment: {
type: "string",
enum: ["bullish", "neutral", "bearish"],
},
confidence: { type: "number" },
},
required: ["sentiment", "confidence"],
}),
},
},
},
async ({ symbol }) => {
const analysis = await analyzeSentiment(symbol);
return {
sentiment: analysis.sentiment,
confidence: analysis.confidence,
};
}
);

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

console.log("Comprehensive MCP server ready with all tool types");

This comprehensive setup provides:

  • System tools for discovering and launching applications/workspaces
  • Working context for user business context awareness
  • Static tools for stable, predictable functionality
  • Dynamic tools for flexible, runtime-controlled capabilities