@interopio/mcp-web
v1.2.1
Published
MCP Web Client and Server
Readme
@interopio/mcp-web
Table of Contents
Introduction
@interopio/mcp-web is a TypeScript library that enables web applications to serve and consume Model Context Protocol (MCP) capabilities within a browser environment. The package provides two distinct functionalities:
- MCP Server - Delivers the capabilities of
@interopio/mcp-corefrom web applications, without requiring a traditional Node.js server environment - MCP Client - Allows web applications to connect as MCP clients to the MCP Server component
Key Features
- Web-based MCP transport implementation using io.Connect Browser
- Seamless integration with io.Connect Browser as a plugin or standalone
- Full MCP specification compliance
- TypeScript support with comprehensive type definitions
- Built-in schema validation and error handling
- Support for all MCP capabilities: tools, resources, prompts, and sampling
Target Audience
This package is designed for developers building web applications in io.Connect Browser environments who need to expose or consume MCP capabilities without running traditional server infrastructure.
Installation
Install the package using npm:
npm install @interopio/mcp-webOr using yarn:
yarn add @interopio/mcp-webRequirements
@interopio/browseror@interopio/desktop- io.Connect Browser/Desktop API@interopio/mcp-core- Core MCP implementation (peer dependency)@modelcontextprotocol/sdk- Model Context Protocol SDK
Core Concepts
Web Transport
Traditional MCP implementations use standard I/O or HTTP-based transports. @interopio/mcp-web implements a custom web transport layer using io.Connect Browser's interop system, enabling MCP communication between web applications without requiring external servers.
Server vs Client
- MCP Server: Exposes MCP capabilities (tools, resources, prompts) that can be consumed by MCP clients. The server uses
@interopio/mcp-coreinternally to provide these capabilities. - MCP Client: Connects to an MCP server to discover and invoke available capabilities. The client implements the MCP client specification from
@modelcontextprotocol/sdk.
io.Connect Integration
The package leverages io.Connect Browser's interop methods for communication:
- Server registers the method
io.mcp.web.serverto receive client requests - Client registers the method
io.mcp.web.clientto receive server responses - Communication is instance-specific, supporting multiple client connections
API Reference
ClientFactory
Factory function to create an MCP client instance.
type IoIntelMCPWebClientFactoryFunction = (
io: IOConnectBrowser.API | IOConnectDesktop.API,
config: IoIntelMCPWeb.Client.Config,
) => Promise<IoIntelMCPWeb.Client.API>;Parameters:
io: io.Connect Browser or Desktop API instanceconfig: Client configuration object
Returns: Promise that resolves to the Client API
Example:
import { ClientFactory } from "@interopio/mcp-web";
const clientApi = await ClientFactory(io, {
capabilities: {
sampling: {},
elicitation: {},
},
});ServerFactory
Factory function to create and start an MCP server instance.
type IoIntelMCPWebServerFactoryFunction = (
io: IOConnectBrowser.API | IOConnectDesktop.API,
config: IoIntelMCPWeb.Server.Config,
) => Promise<void>;Parameters:
io: io.Connect Browser or Desktop API instanceconfig: Server configuration object including license key
Returns: Promise that resolves when server is started
Example:
import { ServerFactory } from "@interopio/mcp-web";
await ServerFactory(io, {
licenseKey: "your-license-key",
mcpCoreServer: {
tools: {
static: {
methods: [...],
intents: [...]
}
}
}
});Client Configuration
interface Config {
enforceStrictCapabilities?: boolean; // default: true
debouncedNotificationMethods?: string[]; // default: []
capabilities: {
sampling?: Record<string, any>;
elicitation?: Record<string, any>;
experimental?: Record<string, any>;
};
}Properties:
enforceStrictCapabilities: Whentrue, enforces strict capability checking against server capabilitiesdebouncedNotificationMethods: Array of notification method names to debouncecapabilities: Client capabilities to advertise to the serversampling: Sampling capability configurationelicitation: Elicitation capability configurationexperimental: Experimental features configuration
Server Configuration
interface Config {
licenseKey: string;
mcpCoreServer?: Omit<IoIntelMCPCore.McpServerConfig, "name" | "title">;
mcpWorkingContext?: IoIntelMCPCore.WorkingContextConfig;
}Properties:
licenseKey: Required. io.Intelligence license keymcpCoreServer: Optional MCP Core server configuration (tools, resources, prompts, etc.)mcpWorkingContext: Optional working context configuration for MCP Core
Note: The
nameandtitlefields are automatically set to "iointel-mcp-web" and "IOIntel MCP Web" respectively.
Client API
The Client API provides access to the underlying MCP client instance.
interface API {
mcpClient: MCPClient;
}Properties:
mcpClient: The@modelcontextprotocol/sdkClient instance with full MCP client capabilities
Common Client Operations:
// List available tools
const tools = await clientApi.mcpClient.listTools();
// Call a tool
const result = await clientApi.mcpClient.callTool({
name: "tool-name",
arguments: {
/* tool arguments */
},
});
// List available resources
const resources = await clientApi.mcpClient.listResources();
// Read a resource
const resource = await clientApi.mcpClient.readResource({
uri: "resource://example",
});
// List available prompts
const prompts = await clientApi.mcpClient.listPrompts();
// Get a prompt
const prompt = await clientApi.mcpClient.getPrompt({
name: "prompt-name",
arguments: {
/* prompt arguments */
},
});Configuration
Client Configuration Options
| Option | Type | Required | Default | Description |
| ------------------------------ | -------- | -------- | ------- | ------------------------------------ |
| capabilities | object | Yes | - | Client capabilities to advertise |
| capabilities.sampling | object | No | - | Sampling capability configuration |
| capabilities.elicitation | object | No | - | Elicitation capability configuration |
| capabilities.experimental | object | No | - | Experimental features configuration |
| enforceStrictCapabilities | boolean | No | true | Enforce strict capability checking |
| debouncedNotificationMethods | string[] | No | [] | Notification methods to debounce |
Configuration Rules:
- The
capabilitiesobject must be provided with at least one capability defined enforceStrictCapabilitiesdefaults totruefor safer operation- Debounced notification methods help reduce redundant notifications for high-frequency events
Server Configuration Options
| Option | Type | Required | Default | Description |
| ------------------- | ------ | -------- | ------- | ----------------------------- |
| licenseKey | string | Yes | - | io.Intelligence license key |
| mcpCoreServer | object | No | {} | MCP Core server configuration |
| mcpWorkingContext | object | No | - | Working context configuration |
Configuration Rules:
licenseKeyis mandatory and must be a valid io.Intelligence licensemcpCoreServeraccepts any valid@interopio/mcp-coreconfiguration exceptnameandtitle- Refer to
@interopio/mcp-coredocumentation for detailed server configuration options
Integration Options
Server as io.Connect Browser Plugin
The recommended approach for io.Connect Browser Platform administrators is to define the MCP server as a plugin. This provides centralized control over MCP capabilities.
Advantages:
- Centralized configuration and management
- Single server instance for all connected clients
- Platform-level control over capabilities
- Automatic lifecycle management
Example:
import IOBrowserPlatform from "@interopio/browser-platform";
import { ServerFactory } from "@interopio/mcp-web";
const platformConfig = {
plugins: {
definitions: [
{
name: "io.MCPWeb",
start: ServerFactory,
critical: true,
config: {
licenseKey: "your-license-key",
mcpCoreServer: {
tools: {
static: {
methods: [...],
intents: [...]
}
}
}
}
}
]
}
};
await IOBrowserPlatform(platformConfig);Server within Web Application
Developers can also instantiate the MCP server directly within their web application.
Advantages:
- Application-specific configuration
- Full control over server lifecycle
- Custom capability exposure
Example:
import IOBrowser from "@interopio/browser";
import { ServerFactory } from "@interopio/mcp-web";
const io = await IOBrowser();
await ServerFactory(io, {
licenseKey: "your-license-key",
mcpCoreServer: {
tools: {
static: {
methods: [
{
name: "calculate",
description: "Perform calculation",
inputSchema: {
type: "object",
properties: {
operation: { type: "string" },
a: { type: "number" },
b: { type: "number" },
},
},
},
],
},
},
},
});Client in Web Application
Any web application can become an MCP client to consume capabilities from the MCP server.
Example:
import IOBrowser from "@interopio/browser";
import { ClientFactory } from "@interopio/mcp-web";
const io = await IOBrowser();
const clientApi = await ClientFactory(io, {
enforceStrictCapabilities: true,
capabilities: {
sampling: {},
elicitation: {},
},
});
// Use the MCP client
const tools = await clientApi.mcpClient.listTools();
console.log("Available tools:", tools);Examples
Basic Server Setup (Plugin)
Configure MCP server as an io.Connect Browser plugin:
import IOBrowserPlatform from "@interopio/browser-platform";
import { ServerFactory, IoIntelMCPWeb } from "@interopio/mcp-web";
const mcpWebServerConfig: IoIntelMCPWeb.Server.Config = {
licenseKey: process.env.IO_INTELLIGENCE_LICENSE_KEY,
mcpCoreServer: {
tools: {
static: {
methods: [
{
name: "getUserInfo",
description: "Get current user information",
inputSchema: {
type: "object",
properties: {},
},
},
],
},
},
},
};
const platformConfig = {
plugins: {
definitions: [
{
name: "io.MCPWeb",
start: ServerFactory,
critical: true,
config: mcpWebServerConfig,
},
],
},
};
const { io, platform } = await IOBrowserPlatform(platformConfig);Basic Server Setup (Direct)
Start an MCP server directly in your application:
import IOBrowser from "@interopio/browser";
import { ServerFactory } from "@interopio/mcp-web";
async function startMCPServer() {
const io = await IOBrowser();
await ServerFactory(io, {
licenseKey: "your-license-key-here",
mcpCoreServer: {
tools: {
static: {
methods: [
{
name: "echo",
description: "Echo back the input message",
inputSchema: {
type: "object",
properties: {
message: { type: "string" },
},
required: ["message"],
},
},
],
},
},
},
});
console.log("MCP Server started successfully");
}
startMCPServer();Basic Client Setup
Connect to an MCP server from a web application:
import IOBrowser from "@interopio/browser";
import { ClientFactory } from "@interopio/mcp-web";
async function connectToMCPServer() {
const io = await IOBrowser();
const clientApi = await ClientFactory(io, {
capabilities: {
sampling: {},
elicitation: {},
},
});
// List available tools
const toolsResult = await clientApi.mcpClient.listTools();
console.log("Available tools:", toolsResult.tools);
// Call a tool
const result = await clientApi.mcpClient.callTool({
name: "echo",
arguments: { message: "Hello, MCP!" },
});
console.log("Tool result:", result);
}
connectToMCPServer();Client with Custom Capabilities
Configure a client with specific capabilities and options:
import IOBrowser from "@interopio/browser";
import { ClientFactory } from "@interopio/mcp-web";
async function advancedClientSetup() {
const io = await IOBrowser();
const clientApi = await ClientFactory(io, {
enforceStrictCapabilities: true,
debouncedNotificationMethods: ["notifications/resources/list_changed"],
capabilities: {
sampling: {
maxTokens: 1000,
temperature: 0.7,
},
elicitation: {
enabled: true,
},
experimental: {
featureX: { enabled: true },
},
},
});
// Client is now ready with custom capabilities
const resources = await clientApi.mcpClient.listResources();
console.log("Available resources:", resources);
}
advancedClientSetup();Complete Integration Example
A full example showing server and client integration in separate applications:
Application 1 (Server):
import IOBrowser from "@interopio/browser";
import { ServerFactory } from "@interopio/mcp-web";
async function startServer() {
const io = await IOBrowser({
application: "mcp-server-app",
});
await ServerFactory(io, {
licenseKey: "your-license-key",
mcpCoreServer: {
tools: {
static: {
methods: [
{
name: "getWeather",
description: "Get weather for a location",
inputSchema: {
type: "object",
properties: {
location: {
type: "string",
description: "City name",
},
},
required: ["location"],
},
},
],
},
},
resources: {
static: [
{
uri: "config://app-settings",
name: "Application Settings",
mimeType: "application/json",
},
],
},
},
});
console.log("MCP Server is running");
}
startServer();Application 2 (Client):
import IOBrowser from "@interopio/browser";
import { ClientFactory } from "@interopio/mcp-web";
async function startClient() {
const io = await IOBrowser({
application: "mcp-client-app",
});
const clientApi = await ClientFactory(io, {
enforceStrictCapabilities: true,
capabilities: {
sampling: {},
elicitation: {},
},
});
// Discover available tools
const { tools } = await clientApi.mcpClient.listTools();
console.log(
"Available tools:",
tools.map((t) => t.name),
);
// Call the weather tool
const weatherResult = await clientApi.mcpClient.callTool({
name: "getWeather",
arguments: { location: "London" },
});
console.log("Weather result:", weatherResult.content);
// List available resources
const { resources } = await clientApi.mcpClient.listResources();
console.log(
"Available resources:",
resources.map((r) => r.uri),
);
// Read a resource
const settingsResource = await clientApi.mcpClient.readResource({
uri: "config://app-settings",
});
console.log("Settings:", settingsResource.contents);
}
startClient();