mcp-client
Version:
An MCP client for Node.js
151 lines • 4.35 kB
JavaScript
// src/MCPClient.ts
import {
Client
} from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import {
ListPromptsResultSchema,
ListResourcesResultSchema,
ListToolsResultSchema,
LoggingMessageNotificationSchema
} from "@modelcontextprotocol/sdk/types.js";
import EventEmitter from "events";
import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
var transformRequestOptions = (requestOptions) => {
return {
onprogress: requestOptions.onProgress,
signal: requestOptions.signal,
timeout: requestOptions.timeout
};
};
var MCPClientEventEmitterBase = EventEmitter;
var MCPClientEventEmitter = class extends MCPClientEventEmitterBase {
};
async function fetchAllPages(client, requestParams, schema, getItems, requestOptions) {
const allItems = [];
let cursor;
do {
const params = { ...requestParams.params || {} };
if (cursor) {
params.cursor = cursor;
}
const response = await client.request(
{ method: requestParams.method, params },
schema,
requestOptions ? transformRequestOptions(requestOptions) : void 0
);
allItems.push(...getItems(response));
cursor = response.nextCursor;
} while (cursor);
return allItems;
}
var MCPClient = class extends MCPClientEventEmitter {
client;
transports = [];
constructor(clientInfo, options) {
super();
this.client = new Client(clientInfo, options);
this.client.setNotificationHandler(
LoggingMessageNotificationSchema,
(message) => {
if (message.method === "notifications/message") {
this.emit("loggingMessage", {
level: message.params.level,
...message.params.data ?? {}
});
}
}
);
}
async connect(options) {
if (options.type === "sse") {
const transport = new SSEClientTransport(new URL(options.url));
this.transports.push(transport);
await this.client.connect(transport);
} else if (options.type === "stdio") {
const transport = new StdioClientTransport({
command: options.command,
env: options.env,
args: options.args
});
this.transports.push(transport);
} else {
throw new Error(`Unknown transport type`);
}
}
async ping(options) {
await this.client.ping(options?.requestOptions);
return null;
}
async getAllTools(options) {
return fetchAllPages(
this.client,
{ method: "tools/list" },
ListToolsResultSchema,
(result) => result.tools,
options?.requestOptions
);
}
async getAllResources(options) {
return fetchAllPages(
this.client,
{ method: "resources/list" },
ListResourcesResultSchema,
(result) => result.resources,
options?.requestOptions
);
}
async getAllPrompts(options) {
return fetchAllPages(
this.client,
{ method: "prompts/list" },
ListPromptsResultSchema,
(result) => result.prompts,
options?.requestOptions
);
}
async callTool(invocation, options) {
return await this.client.callTool(
invocation,
options?.resultSchema,
options?.requestOptions ? transformRequestOptions(options.requestOptions) : void 0
);
}
async complete(params, options) {
return await this.client.complete(params, options?.requestOptions);
}
async getResource(params, options) {
return await this.client.readResource(params, options?.requestOptions);
}
async getPrompt(params, options) {
return await this.client.getPrompt(params, options?.requestOptions);
}
async getAllResourceTemplates(options) {
let cursor;
const allItems = [];
do {
const response = await this.client.listResourceTemplates(
{ cursor },
options?.requestOptions
);
allItems.push(...response.resourceTemplates);
cursor = response.nextCursor;
} while (cursor);
return allItems;
}
async setLoggingLevel(level) {
await this.client.setLoggingLevel(level);
}
async close() {
for (const transport of this.transports) {
await transport.close();
}
}
};
export {
ErrorCode,
MCPClient,
McpError
};
//# sourceMappingURL=MCPClient.js.map