@discreted/vue-browser-tabs
Version:
A browser-like tabs component for Vue3
131 lines (130 loc) • 3.6 kB
JavaScript
class a {
constructor() {
this.requestId = 0, this.pendingRequests = /* @__PURE__ */ new Map(), this.tools = /* @__PURE__ */ new Map(), this.isConnected = !1, this.handleMessage = (e) => {
if (e.source !== this.parentWindow)
return;
const t = e.data;
if (t && t.type === "MCP_PROXY_RESPONSE") {
const { id: r, result: s, error: i } = t.data, n = this.pendingRequests.get(r);
n && (this.pendingRequests.delete(r), i ? n.reject(new Error(i)) : n.resolve(s));
}
if (t && t.type === "MCP_PROXY_TOOL_CALL") {
const { id: r, toolName: s, args: i } = t.data;
this.handleToolCall(r, s, i);
}
}, this.parentWindow = window.parent || window.opener || window, this.targetOrigin = "*", window.addEventListener("message", this.handleMessage);
}
/**
* 发送请求到父应用的MCP服务
* @param method 方法名
* @param params 参数
* @returns Promise
*/
sendRequest(e, t = {}) {
return !this.isConnected && e !== "ping" ? Promise.reject(new Error("MCP代理客户端未连接到父应用")) : new Promise((r, s) => {
const i = ++this.requestId;
this.pendingRequests.set(i, { resolve: r, reject: s });
const n = {
type: "MCP_PROXY_REQUEST",
data: { id: i, method: e, params: t }
};
this.parentWindow.postMessage(n, this.targetOrigin), setTimeout(() => {
this.pendingRequests.has(i) && (this.pendingRequests.delete(i), s(new Error(`Request timeout: ${e}`)));
}, 5e3);
});
}
/**
* 处理工具调用请求
* @param id 调用ID
* @param toolName 工具名称
* @param args 工具参数
*/
async handleToolCall(e, t, r) {
try {
const s = this.tools.get(t);
if (!s) {
this.parentWindow.postMessage(
{
type: "MCP_PROXY_TOOL_CALL_RESPONSE",
data: {
id: e,
error: `Tool not found: ${t}`
}
},
this.targetOrigin
);
return;
}
const i = await s.implementation(r);
this.parentWindow.postMessage(
{
type: "MCP_PROXY_TOOL_CALL_RESPONSE",
data: { id: e, result: i }
},
this.targetOrigin
);
} catch (s) {
this.parentWindow.postMessage(
{
type: "MCP_PROXY_TOOL_CALL_RESPONSE",
data: {
id: e,
error: s.message || "Unknown error occurred"
}
},
this.targetOrigin
);
}
}
/**
* 注册工具
* @param name 工具名称
* @param toolDefinition 工具定义
*/
async registerTool(e, t) {
const { description: r, parameters: s } = t;
this.tools.set(e, t);
try {
await this.sendRequest("registerTool", {
name: e,
description: r,
parameters: s
});
} catch (i) {
throw this.tools.delete(e), i;
}
}
/**
* 调用工具
* @param name 工具名称
* @param args 工具参数
* @returns 工具执行结果
*/
async callTool(e, t = {}) {
return await this.sendRequest("callTool", { name: e, arguments: t });
}
/**
* 获取工具列表
* @returns 工具列表
*/
async listTools() {
return await this.sendRequest("listTools");
}
/**
* 设置目标源
* @param origin 目标源
*/
setTargetOrigin(e) {
this.targetOrigin = e, this.isConnected = !0;
}
/**
* 检查连接状态
* @returns 连接状态
*/
get connected() {
return this.isConnected;
}
}
export {
a as McpProxyClient
};