@xopcai/xopc 0.0.157 → 0.0.159
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/dashscope/src/image-generation-provider.js +1 -1
- package/dist/extensions/fal/src/image-generation-provider.js +1 -1
- package/dist/extensions/google/src/image-generation-provider.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{action-boundary-settings-panel-zQ_w0sPl.js → action-boundary-settings-panel-CaRK2vIy.js} +1 -1
- package/dist/gateway/static/root/assets/{activity-store-CddlQHam.js → activity-store-C-57rvkX.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DOfTopIk.js → agent-avatar-dicebear-BeVf03hx.js} +1 -1
- package/dist/gateway/static/root/assets/agents-P05C4A-3.js +2 -0
- package/dist/gateway/static/root/assets/{api-NUlcaaV9.js → api-BjcBIV2O.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-J0-z_uc1.js → app-management-settings-panel-BG2ulMYw.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CMaQOx2C.js → appearance-settings-0Kjenr2T.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DANGrBpN.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BVwE70GV.js → archive-plugin-ChiNnH1e.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-aj5U56K9.js → attachment-load-pbBlQR-g.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-CKz8rxAb.js → automation-suggestion-card-CTZDOyDy.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-BXfGL_cm.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-Ie6owbEw.js → binary-plugins-BeZGzpGF.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-BaDrd5GJ.js → block-editor-BnDmhN5Z.js} +3 -3
- package/dist/gateway/static/root/assets/browser-settings-page-534luV0B.js +8 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-BjO4YD-O.js → capability-presets-api-Ii36j_7v.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-bwezWQpF.js → capability-presets-settings-panel-Cl3dw4yh.js} +2 -2
- package/dist/gateway/static/root/assets/{channel-recipient-api-BisDU_DH.js → channel-recipient-api-CFqrSi5K.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-M91zFJVi.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-vooEF4lG.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-DGjjzBIH.js → connector-logo-CiLxuZ8S.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-CV5UulW6.js +2 -0
- package/dist/gateway/static/root/assets/{desktop-pet-CoQ4Edck.js → desktop-pet-Cil2eSpW.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings--sjUYeNX.js → desktop-pet-settings-DwsC6l5F.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-CpmfFDx3.js → directory-picker-path-field-CC2VL5Mc.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-D7rRROE7.js → dreaming-settings-KY7ZfVsy.js} +3 -3
- package/dist/gateway/static/root/assets/{extension-debug-page-BzqW3ssG.js → extension-debug-page-C8KBeucs.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CKDbBzVR.js → extension-page-CV-5Kcyk.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DjNMSdRz.js → extension-settings-page-DvUtDrAu.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-CUEAZEld.js → gateway-config-api-DXfVeJLc.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-BpJ0v56l.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CbMPgpHX.js → gateway-startup-retry-cxQ94qMm.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-lMHD-2CX.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-yPmF-G7b.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-C-Vq8VR9.js → goals-config-api-P8VhLqYF.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-BHTCKobG.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-DVrTDWYS.js → goals-settings-DHXyaH_O.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-Dv8qA4E7.js → heartbeat-settings-CNckP_Dv.js} +1 -1
- package/dist/gateway/static/root/assets/index-BgZhEOkN.css +1 -0
- package/dist/gateway/static/root/assets/{index-DHRxn7Sy.js → index-BuqGh2SW.js} +65 -65
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DEKtMZbg.js → keyboard-shortcuts-settings-jXmv1RVX.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-zpp_wciE.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-DQT2lZk7.js → local-apps-page-Cs5LKjtc.js} +1 -1
- package/dist/gateway/static/root/assets/locale-store-C_M71MK9.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-B4CRYqYR.js +7 -0
- package/dist/gateway/static/root/assets/{markdown-split-Cp6NxQJr.js → markdown-split-BFqeSNte.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Dv1cQK2J.js → media-plugins-Cc8379gq.js} +1 -1
- package/dist/gateway/static/root/assets/{messages-Bwu1tG3T.js → messages-BuT0SR1R.js} +4 -4
- package/dist/gateway/static/root/assets/models-hub-panel-1hdoAoB_.js +2 -0
- package/dist/gateway/static/root/assets/{notes-page-CePZ2we1.js → notes-page-DlGU4ipo.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-DQEAZTA5.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-C1jBfKTZ.js → page-tabs-kFOswGlG.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Cl9anbg0.js → preview-open-alternatives-CvjuvABg.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-Bp9bC7A6.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-RNorFXTw.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-BqRTcM_6.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-CWu_o1ta.js → save-bar-controls-DwrD7ODx.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-DuZbqL7X.js → schedule-field-Ba4WzTmE.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-Bixut-2d.js → schema-form-DvydL8eF.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-B2EfW1cm.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CklL85T4.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-C_7lCtCp.js → settings-collapsible-section-LaQqGGej.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-D0DPTbO0.js → settings-form-section-DruI__qO.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-tN-9u8dj.js → settings-loading-skeleton-UvA-eDhF.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-C2L9g3kd.js → settings-page-5oCGSebm.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-CBUOPmx_.js → settings-page-layout-DG-XMIPu.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-D3my1HgB.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BiSh0nLu.js → share-preview-page-FLVeTrRt.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DVxgjrsP.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-Bcu58ZaF.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-CDd-84FE.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-h7uqbQ-n.js → system-settings-panel-CeK93xVi.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-DjYRaF0J.js → theme-store-C8ohIHhw.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-BkqBD32C.js → typed-models-lib-D1Lr2gG0.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-DiWtF12K.js → use-channel-catalog-BWzou5ar.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-1OyJnTyR.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-C4770AsA.js → voice-api-key-field-B2ncRwHS.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-page-BZlY4PZL.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-DPXMrneY.js +1 -0
- package/dist/gateway/static/root/assets/work-page-CTERoqyv.js +1 -0
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-Bynqe4kV.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-CLgsnqFQ.js +11 -0
- package/dist/gateway/static/root/index.html +7 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +14 -0
- package/dist/src/agent/image/generation/openai-compatible-image-provider.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +10 -3
- package/dist/src/agent/tools/send-media.js +20 -70
- package/dist/src/agent/tools/tool-media.d.ts +9 -0
- package/dist/src/agent/tools/tool-media.js +58 -0
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/connectors/catalog.js +2 -3
- package/dist/src/connectors/composio-catalog.d.ts +11 -1
- package/dist/src/connectors/composio-catalog.js +37 -7
- package/dist/src/connectors/composio.js +2 -1
- package/dist/src/gateway/agent-run-relay.d.ts +2 -0
- package/dist/src/gateway/agent-run-relay.js +114 -14
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/chat-stream/mapper.d.ts +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +27 -42
- package/dist/src/gateway/chat-stream/thinking-delta-coalescer.d.ts +7 -0
- package/dist/src/gateway/chat-stream/thinking-delta-coalescer.js +103 -0
- package/dist/src/gateway/hono/routes/connectors.js +10 -22
- package/dist/src/gateway/hono/sse.d.ts +1 -1
- package/dist/src/gateway/hono/sse.js +1 -1
- package/dist/src/gateway/service/run-gateway-agent.js +5 -1
- package/dist/src/media/session-references.js +9 -6
- package/dist/src/session/client-history.d.ts +1 -0
- package/dist/src/session/client-history.js +56 -12
- package/dist/src/session/types.d.ts +1 -0
- package/dist/src/storage/sqlite/connector-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/connector-repository.js +12 -1
- package/dist/src/storage/sqlite/index.d.ts +1 -1
- package/dist/src/storage/sqlite/index.js +2 -2
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/agents-RZNd9xMI.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-BOeTZgdL.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-wYN1N-Il.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-DD3djQtX.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-Bohv9YRy.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-h3VHD5Uq.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-LIAkMlN-.js +0 -2
- package/dist/gateway/static/root/assets/gateway-settings-h1wWBrxD.js +0 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-xfO0R5Bx.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-CVVKF2hY.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-W666NFIU.js +0 -2
- package/dist/gateway/static/root/assets/index-gpwk8Nro.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-y5WmNSyZ.js +0 -2
- package/dist/gateway/static/root/assets/locale-store-d9Cylz62.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-DMQaC4Jn.js +0 -7
- package/dist/gateway/static/root/assets/models-hub-panel-CoYDJvX_.js +0 -2
- package/dist/gateway/static/root/assets/notes-workbench-C9B-7EsK.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-DG_P8S7e.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-C1pro-bG.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DDj6t0SQ.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-C1aZFTTX.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CwRP1Nsl.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DFjG5i48.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-Bh2T05Hp.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-ppRtNzpM.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-Dnw1xKKm.js +0 -2
- package/dist/gateway/static/root/assets/user-context-page-09T5O8lO.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-D__GQy1R.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-CAIgG4im.js +0 -1
- package/dist/gateway/static/root/assets/work-page-CkZvIUpT.js +0 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-qqixrSRL.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-THxdPWzb.js +0 -11
- package/dist/src/connectors/registries/modelscope.d.ts +0 -2
- package/dist/src/connectors/registries/modelscope.js +0 -228
- package/dist/src/connectors/registries/official-mcp.d.ts +0 -2
- package/dist/src/connectors/registries/official-mcp.js +0 -140
- package/dist/src/connectors/registries/search.d.ts +0 -12
- package/dist/src/connectors/registries/search.js +0 -87
- package/dist/src/connectors/registries/smithery.d.ts +0 -2
- package/dist/src/connectors/registries/smithery.js +0 -97
- package/dist/src/connectors/registries/types.d.ts +0 -20
- package/dist/src/connectors/registries/types.js +0 -1
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
//#region src/connectors/registries/modelscope.ts
|
|
2
|
-
const DEFAULT_BASE_URL = "https://www.modelscope.cn";
|
|
3
|
-
function modelscopeBaseUrl() {
|
|
4
|
-
return process.env.XOPC_MODELSCOPE_REGISTRY_URL?.trim().replace(/\/+$/, "") || DEFAULT_BASE_URL;
|
|
5
|
-
}
|
|
6
|
-
function readString(value) {
|
|
7
|
-
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
8
|
-
}
|
|
9
|
-
function readArray(value) {
|
|
10
|
-
return Array.isArray(value) ? value : [];
|
|
11
|
-
}
|
|
12
|
-
function readRecord(value) {
|
|
13
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
14
|
-
}
|
|
15
|
-
function isHttpUrl(value) {
|
|
16
|
-
return value?.startsWith("http://") || value?.startsWith("https://") || false;
|
|
17
|
-
}
|
|
18
|
-
function slugFrom(value) {
|
|
19
|
-
return value.trim().toLowerCase().replace(/^@/, "").replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "modelscope-mcp";
|
|
20
|
-
}
|
|
21
|
-
function categoryFromModelScope(categories) {
|
|
22
|
-
const text = readArray(categories).map((item) => readString(item)).filter(Boolean).join(" ").toLowerCase();
|
|
23
|
-
if (text.includes("browser")) return "browser";
|
|
24
|
-
if (text.includes("automation")) return "automation";
|
|
25
|
-
if (text.includes("database") || text.includes("data")) return "data";
|
|
26
|
-
if (text.includes("code") || text.includes("developer")) return "code";
|
|
27
|
-
if (text.includes("docs") || text.includes("knowledge")) return "docs";
|
|
28
|
-
return "custom";
|
|
29
|
-
}
|
|
30
|
-
function secretFieldsFromEnvSchema(schema) {
|
|
31
|
-
const record = readRecord(schema);
|
|
32
|
-
const properties = readRecord(record?.properties);
|
|
33
|
-
if (!properties) return [];
|
|
34
|
-
const required = new Set(readArray(record?.required).map((item) => readString(item)).filter((item) => Boolean(item)));
|
|
35
|
-
return Object.entries(properties).map(([key, value]) => {
|
|
36
|
-
return {
|
|
37
|
-
key,
|
|
38
|
-
label: key,
|
|
39
|
-
description: readString(readRecord(value)?.description),
|
|
40
|
-
required: required.size === 0 ? true : required.has(key)
|
|
41
|
-
};
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
function readMcpServerConfigs(value) {
|
|
45
|
-
const configItems = Array.isArray(value) ? value : [value];
|
|
46
|
-
const configs = [];
|
|
47
|
-
for (const config of configItems) {
|
|
48
|
-
const configRecord = readRecord(config);
|
|
49
|
-
if (!configRecord) continue;
|
|
50
|
-
const mcpServers = readRecord(configRecord?.mcpServers);
|
|
51
|
-
if (!mcpServers) {
|
|
52
|
-
configs.push(configRecord);
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
for (const value of Object.values(mcpServers)) {
|
|
56
|
-
const serverConfig = readRecord(value);
|
|
57
|
-
if (serverConfig) configs.push(serverConfig);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return configs;
|
|
61
|
-
}
|
|
62
|
-
function firstMcpServerConfig(server, predicate = (config) => Boolean(readString(config.command))) {
|
|
63
|
-
for (const config of readMcpServerConfigs(server.ServerConfig ?? server.serverConfig)) if (predicate(config)) return config;
|
|
64
|
-
}
|
|
65
|
-
function secretFieldsFromServerConfig(server) {
|
|
66
|
-
const env = readRecord((firstMcpServerConfig(server, (candidate) => Boolean(readRecord(candidate.env))) ?? firstMcpServerConfig(server))?.env);
|
|
67
|
-
if (!env) return [];
|
|
68
|
-
return Object.keys(env).map((key) => ({
|
|
69
|
-
key,
|
|
70
|
-
label: key,
|
|
71
|
-
description: `Environment variable required by the ModelScope MCP server config.`,
|
|
72
|
-
required: true
|
|
73
|
-
}));
|
|
74
|
-
}
|
|
75
|
-
function mergeSecretFields(...groups) {
|
|
76
|
-
const merged = /* @__PURE__ */ new Map();
|
|
77
|
-
for (const group of groups) for (const field of group) {
|
|
78
|
-
const previous = merged.get(field.key);
|
|
79
|
-
merged.set(field.key, {
|
|
80
|
-
...field,
|
|
81
|
-
description: previous?.description ?? field.description,
|
|
82
|
-
required: previous?.required ?? field.required
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
return [...merged.values()];
|
|
86
|
-
}
|
|
87
|
-
function normalizeEnv(env, secrets) {
|
|
88
|
-
const envRecord = readRecord(env);
|
|
89
|
-
const output = {};
|
|
90
|
-
for (const [key, value] of Object.entries(envRecord ?? {})) output[key] = secrets.some((field) => field.key === key) ? `{{secrets.${key}}}` : value;
|
|
91
|
-
for (const field of secrets) if (output[field.key] === void 0) output[field.key] = `{{secrets.${field.key}}}`;
|
|
92
|
-
return Object.keys(output).length ? output : void 0;
|
|
93
|
-
}
|
|
94
|
-
function transportFromConfig(config, fallback) {
|
|
95
|
-
return (readString(config.transport ?? config.type)?.toLowerCase())?.includes("sse") ? "sse" : fallback;
|
|
96
|
-
}
|
|
97
|
-
function normalizeServerTemplate(server, secrets) {
|
|
98
|
-
const deployedUrl = readString(server.DeployedUrl ?? server.deployedUrl);
|
|
99
|
-
if (isHttpUrl(deployedUrl)) return {
|
|
100
|
-
url: deployedUrl,
|
|
101
|
-
transport: readString(server.DeployedUrlTransportType ?? server.deployedUrlTransportType)?.toLowerCase() === "sse" ? "sse" : "streamable-http"
|
|
102
|
-
};
|
|
103
|
-
for (const key of [
|
|
104
|
-
"StreamableHTTPServerConfig",
|
|
105
|
-
"streamableHTTPServerConfig",
|
|
106
|
-
"SSEServerConfig",
|
|
107
|
-
"sseServerConfig"
|
|
108
|
-
]) {
|
|
109
|
-
const fallbackTransport = key.toLowerCase().includes("sse") ? "sse" : "streamable-http";
|
|
110
|
-
for (const config of readMcpServerConfigs(server[key])) {
|
|
111
|
-
const url = readString(config.url ?? config.endpoint);
|
|
112
|
-
if (isHttpUrl(url)) return {
|
|
113
|
-
url,
|
|
114
|
-
transport: transportFromConfig(config, fallbackTransport)
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
const remoteConfig = firstMcpServerConfig(server, (candidate) => isHttpUrl(readString(candidate.url ?? candidate.endpoint)));
|
|
119
|
-
const remoteUrl = readString(remoteConfig?.url ?? remoteConfig?.endpoint);
|
|
120
|
-
if (isHttpUrl(remoteUrl) && remoteConfig) return {
|
|
121
|
-
url: remoteUrl,
|
|
122
|
-
transport: transportFromConfig(remoteConfig, "streamable-http")
|
|
123
|
-
};
|
|
124
|
-
const config = firstMcpServerConfig(server);
|
|
125
|
-
const command = readString(config?.command);
|
|
126
|
-
if (!command) return void 0;
|
|
127
|
-
const args = readArray(config?.args).map((arg) => String(arg));
|
|
128
|
-
const env = normalizeEnv(config.env, secrets);
|
|
129
|
-
return {
|
|
130
|
-
command,
|
|
131
|
-
...args.length ? { args } : {},
|
|
132
|
-
...env ? { env } : {},
|
|
133
|
-
...readString(config.cwd) ? { cwd: readString(config.cwd) } : {}
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
function connectorFromModelScopeServer(server) {
|
|
137
|
-
const name = readString(server.Name ?? server.name);
|
|
138
|
-
const path = readString(server.Path ?? server.path ?? server.FromSitePath ?? server.fromSitePath);
|
|
139
|
-
const displayName = readString(server.ChineseName ?? server.DisplayName ?? server.displayName) || name;
|
|
140
|
-
if (!name || !displayName) return void 0;
|
|
141
|
-
const serverId = slugFrom(path ? `${path}/${name}` : name);
|
|
142
|
-
const secrets = mergeSecretFields(secretFieldsFromEnvSchema(server.EnvSchema ?? server.envSchema), secretFieldsFromServerConfig(server));
|
|
143
|
-
const serverTemplate = normalizeServerTemplate(server, secrets);
|
|
144
|
-
if (!serverTemplate) return void 0;
|
|
145
|
-
const isRemote = typeof serverTemplate.url === "string";
|
|
146
|
-
const tags = [
|
|
147
|
-
...readArray(server.Category ?? server.category).map((tag) => readString(tag)).filter((tag) => Boolean(tag)),
|
|
148
|
-
...readArray(server.Tags ?? server.tags).map((tag) => readString(tag)).filter((tag) => Boolean(tag)),
|
|
149
|
-
"modelscope",
|
|
150
|
-
"registry",
|
|
151
|
-
"mcp"
|
|
152
|
-
];
|
|
153
|
-
return {
|
|
154
|
-
id: `modelscope-${serverId}`,
|
|
155
|
-
version: readString(server.Version ?? server.version) ?? "registry",
|
|
156
|
-
displayName,
|
|
157
|
-
description: readString(server.Abstract ?? server.AbstractCN ?? server.description) ?? "MCP server from ModelScope MCP registry.",
|
|
158
|
-
category: categoryFromModelScope(server.Category ?? server.category),
|
|
159
|
-
kind: "mcp",
|
|
160
|
-
source: "registry",
|
|
161
|
-
capabilities: isRemote ? [
|
|
162
|
-
"tools",
|
|
163
|
-
"resources",
|
|
164
|
-
"prompts",
|
|
165
|
-
"runtime.mcp.streamableHttp"
|
|
166
|
-
] : [
|
|
167
|
-
"tools",
|
|
168
|
-
"resources",
|
|
169
|
-
"prompts",
|
|
170
|
-
"runtime.mcp.stdio"
|
|
171
|
-
],
|
|
172
|
-
tags: Array.from(new Set(tags)).slice(0, 8),
|
|
173
|
-
auth: { mode: secrets.length ? "apiKey" : "none" },
|
|
174
|
-
setup: { secrets: secrets.length ? secrets : void 0 },
|
|
175
|
-
runtime: {
|
|
176
|
-
type: "mcp",
|
|
177
|
-
serverId,
|
|
178
|
-
serverTemplate
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
function readNumber(value) {
|
|
183
|
-
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
184
|
-
}
|
|
185
|
-
function extractMcpServers(payload) {
|
|
186
|
-
const data = readRecord(readRecord(payload)?.Data);
|
|
187
|
-
const nestedData = readRecord(data?.Data) ?? data;
|
|
188
|
-
const mcp = readRecord(nestedData?.Mcp ?? nestedData?.McpServer ?? nestedData?.mcp);
|
|
189
|
-
return {
|
|
190
|
-
servers: readArray(mcp?.McpServers ?? mcp?.servers ?? mcp?.items).map((item) => readRecord(item)).filter((item) => Boolean(item)),
|
|
191
|
-
total: typeof mcp?.TotalCount === "number" ? mcp.TotalCount : void 0
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
async function fetchModelScopeMcp(params) {
|
|
195
|
-
const url = new URL("/api/v1/dolphin/agg", modelscopeBaseUrl());
|
|
196
|
-
const body = {
|
|
197
|
-
PageSize: Math.min(Math.max(params.pageSize ?? 24, 1), 100),
|
|
198
|
-
PageNumber: Math.max(params.page ?? 1, 1),
|
|
199
|
-
Query: params.query?.trim() ?? "",
|
|
200
|
-
Criterion: []
|
|
201
|
-
};
|
|
202
|
-
const response = await fetch(url, {
|
|
203
|
-
method: "PUT",
|
|
204
|
-
headers: {
|
|
205
|
-
Accept: "application/json",
|
|
206
|
-
"Content-Type": "application/json",
|
|
207
|
-
"x-modelscope-accept-language": "zh_CN"
|
|
208
|
-
},
|
|
209
|
-
body: JSON.stringify(body)
|
|
210
|
-
});
|
|
211
|
-
if (!response.ok) throw new Error(`ModelScope registry returned ${response.status}`);
|
|
212
|
-
return response.json();
|
|
213
|
-
}
|
|
214
|
-
const modelscopeRegistryAdapter = {
|
|
215
|
-
source: "modelscope",
|
|
216
|
-
displayName: "ModelScope",
|
|
217
|
-
async search(params) {
|
|
218
|
-
const { servers, total } = extractMcpServers(await fetchModelScopeMcp(params));
|
|
219
|
-
const pageSize = Math.min(Math.max(params.pageSize ?? 24, 1), 100);
|
|
220
|
-
return {
|
|
221
|
-
source: "modelscope",
|
|
222
|
-
connectors: servers.toSorted((a, b) => readNumber(b.CallVolume ?? b.callVolume) - readNumber(a.CallVolume ?? a.callVolume)).map(connectorFromModelScopeServer).filter((item) => Boolean(item)),
|
|
223
|
-
totalPages: total === void 0 ? void 0 : Math.ceil(total / pageSize)
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
//#endregion
|
|
228
|
-
export { modelscopeRegistryAdapter };
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
//#region src/connectors/registries/official-mcp.ts
|
|
2
|
-
const DEFAULT_BASE_URL = "https://registry.modelcontextprotocol.io";
|
|
3
|
-
function officialRegistryBaseUrl() {
|
|
4
|
-
return process.env.XOPC_MCP_OFFICIAL_REGISTRY_URL?.trim().replace(/\/+$/, "") || DEFAULT_BASE_URL;
|
|
5
|
-
}
|
|
6
|
-
function readString(value) {
|
|
7
|
-
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
8
|
-
}
|
|
9
|
-
function readArray(value) {
|
|
10
|
-
return Array.isArray(value) ? value : [];
|
|
11
|
-
}
|
|
12
|
-
function slugFrom(value) {
|
|
13
|
-
return value.trim().toLowerCase().replace(/^@/, "").replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "registry-mcp";
|
|
14
|
-
}
|
|
15
|
-
function normalizePackageCommand(pkg) {
|
|
16
|
-
const registryType = readString(pkg.registryType ?? pkg.registry_type ?? pkg.type)?.toLowerCase();
|
|
17
|
-
const name = readString(pkg.name ?? pkg.packageName ?? pkg.package_name);
|
|
18
|
-
if (!name) return void 0;
|
|
19
|
-
if (registryType === "pypi" || registryType === "python") return {
|
|
20
|
-
command: "uvx",
|
|
21
|
-
args: [name]
|
|
22
|
-
};
|
|
23
|
-
if (registryType === "npm" || registryType === "node" || !registryType) return {
|
|
24
|
-
command: "npx",
|
|
25
|
-
args: ["-y", name]
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
function normalizeRemote(server) {
|
|
29
|
-
const remotes = readArray(server.remotes ?? server.remote ?? server.deployments);
|
|
30
|
-
for (const raw of remotes) {
|
|
31
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
|
|
32
|
-
const row = raw;
|
|
33
|
-
const url = readString(row.url ?? row.endpoint ?? row.deploymentUrl ?? row.deployment_url);
|
|
34
|
-
if (url?.startsWith("http://") || url?.startsWith("https://")) return {
|
|
35
|
-
url,
|
|
36
|
-
transport: "streamable-http"
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
const url = readString(server.url ?? server.endpoint);
|
|
40
|
-
if (url?.startsWith("http://") || url?.startsWith("https://")) return {
|
|
41
|
-
url,
|
|
42
|
-
transport: "streamable-http"
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
function connectorFromOfficialServer(server) {
|
|
46
|
-
const qualifiedName = readString(server.name ?? server.id ?? server.qualifiedName ?? server.qualified_name);
|
|
47
|
-
const displayName = readString(server.displayName ?? server.display_name ?? server.title ?? server.name) ?? qualifiedName;
|
|
48
|
-
if (!qualifiedName || !displayName) return void 0;
|
|
49
|
-
const packageRuntime = readArray(server.packages).map((item) => item && typeof item === "object" && !Array.isArray(item) ? normalizePackageCommand(item) : void 0).find(Boolean);
|
|
50
|
-
const remoteRuntime = normalizeRemote(server);
|
|
51
|
-
const serverId = slugFrom(qualifiedName);
|
|
52
|
-
const serverTemplate = packageRuntime ? {
|
|
53
|
-
command: packageRuntime.command,
|
|
54
|
-
args: packageRuntime.args
|
|
55
|
-
} : remoteRuntime ? {
|
|
56
|
-
url: remoteRuntime.url,
|
|
57
|
-
transport: remoteRuntime.transport
|
|
58
|
-
} : void 0;
|
|
59
|
-
if (!serverTemplate) return void 0;
|
|
60
|
-
const tags = [
|
|
61
|
-
...readArray(server.tags).map((tag) => readString(tag)).filter((tag) => Boolean(tag)),
|
|
62
|
-
"registry",
|
|
63
|
-
"mcp"
|
|
64
|
-
];
|
|
65
|
-
const description = readString(server.description) ?? "MCP server from the official Model Context Protocol registry.";
|
|
66
|
-
const capabilities = packageRuntime ? [
|
|
67
|
-
"tools",
|
|
68
|
-
"resources",
|
|
69
|
-
"prompts",
|
|
70
|
-
"runtime.mcp.stdio"
|
|
71
|
-
] : [
|
|
72
|
-
"tools",
|
|
73
|
-
"resources",
|
|
74
|
-
"prompts",
|
|
75
|
-
"runtime.mcp.streamableHttp"
|
|
76
|
-
];
|
|
77
|
-
return {
|
|
78
|
-
id: `mcp-official-${serverId}`,
|
|
79
|
-
version: readString(server.version) ?? "registry",
|
|
80
|
-
displayName,
|
|
81
|
-
description,
|
|
82
|
-
category: "custom",
|
|
83
|
-
kind: "mcp",
|
|
84
|
-
source: "registry",
|
|
85
|
-
capabilities,
|
|
86
|
-
tags: Array.from(new Set(tags)).slice(0, 8),
|
|
87
|
-
auth: { mode: "none" },
|
|
88
|
-
setup: {},
|
|
89
|
-
runtime: {
|
|
90
|
-
type: "mcp",
|
|
91
|
-
serverId,
|
|
92
|
-
serverTemplate
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
async function fetchJson(url) {
|
|
97
|
-
const response = await fetch(url, { headers: { Accept: "application/json" } });
|
|
98
|
-
if (!response.ok) throw new Error(`Official MCP registry returned ${response.status}`);
|
|
99
|
-
return response.json();
|
|
100
|
-
}
|
|
101
|
-
function normalizeServerRecord(item) {
|
|
102
|
-
if (!item || typeof item !== "object" || Array.isArray(item)) return void 0;
|
|
103
|
-
const record = item;
|
|
104
|
-
const nested = record.server;
|
|
105
|
-
if (nested && typeof nested === "object" && !Array.isArray(nested)) return nested;
|
|
106
|
-
return record;
|
|
107
|
-
}
|
|
108
|
-
function extractServers(payload) {
|
|
109
|
-
if (Array.isArray(payload)) return payload.map(normalizeServerRecord).filter((item) => Boolean(item));
|
|
110
|
-
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return [];
|
|
111
|
-
const data = payload;
|
|
112
|
-
for (const key of [
|
|
113
|
-
"servers",
|
|
114
|
-
"items",
|
|
115
|
-
"results",
|
|
116
|
-
"data"
|
|
117
|
-
]) {
|
|
118
|
-
const value = data[key];
|
|
119
|
-
if (Array.isArray(value)) return value.map(normalizeServerRecord).filter((item) => Boolean(item));
|
|
120
|
-
}
|
|
121
|
-
return [];
|
|
122
|
-
}
|
|
123
|
-
const officialMcpRegistryAdapter = {
|
|
124
|
-
source: "mcp_official",
|
|
125
|
-
displayName: "Official MCP registry",
|
|
126
|
-
async search(params) {
|
|
127
|
-
const base = officialRegistryBaseUrl();
|
|
128
|
-
const url = new URL("/v0/servers", base);
|
|
129
|
-
const query = params.query?.trim();
|
|
130
|
-
if (query) url.searchParams.set("q", query);
|
|
131
|
-
url.searchParams.set("limit", String(Math.min(Math.max(params.pageSize ?? 24, 1), 100)));
|
|
132
|
-
if (params.page && params.page > 1) url.searchParams.set("page", String(params.page));
|
|
133
|
-
return {
|
|
134
|
-
source: "mcp_official",
|
|
135
|
-
connectors: extractServers(await fetchJson(url)).map(connectorFromOfficialServer).filter((item) => Boolean(item))
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
//#endregion
|
|
140
|
-
export { officialMcpRegistryAdapter };
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ConnectorRegistryAdapter, ConnectorRegistrySearchParams, ConnectorRegistrySearchResult } from './types.js';
|
|
2
|
-
export type ConnectorRegistryRegistration = {
|
|
3
|
-
adapter: ConnectorRegistryAdapter;
|
|
4
|
-
};
|
|
5
|
-
export declare function registerConnectorRegistryAdapter(registration: ConnectorRegistryRegistration): void;
|
|
6
|
-
export declare function unregisterConnectorRegistryAdapter(source: string): boolean;
|
|
7
|
-
export declare function listConnectorRegistries(): Array<{
|
|
8
|
-
id: string;
|
|
9
|
-
displayName: string;
|
|
10
|
-
}>;
|
|
11
|
-
export declare function isConnectorRegistrySource(source: string): boolean;
|
|
12
|
-
export declare function searchConnectorRegistries(params: ConnectorRegistrySearchParams): Promise<ConnectorRegistrySearchResult[]>;
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { createLogger } from "../../utils/logger/index.js";
|
|
2
|
-
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { modelscopeRegistryAdapter } from "./modelscope.js";
|
|
4
|
-
import { officialMcpRegistryAdapter } from "./official-mcp.js";
|
|
5
|
-
import { smitheryRegistryAdapter } from "./smithery.js";
|
|
6
|
-
//#region src/connectors/registries/search.ts
|
|
7
|
-
init_logger();
|
|
8
|
-
const log = createLogger("Connectors:Registry");
|
|
9
|
-
const registryAdapters = /* @__PURE__ */ new Map();
|
|
10
|
-
const REGISTRY_CACHE_TTL_MS = 600 * 1e3;
|
|
11
|
-
const registrySearchCache = /* @__PURE__ */ new Map();
|
|
12
|
-
function registerConnectorRegistryAdapter(registration) {
|
|
13
|
-
registryAdapters.set(registration.adapter.source, registration.adapter);
|
|
14
|
-
registrySearchCache.clear();
|
|
15
|
-
}
|
|
16
|
-
function unregisterConnectorRegistryAdapter(source) {
|
|
17
|
-
const removed = registryAdapters.delete(source);
|
|
18
|
-
if (removed) registrySearchCache.clear();
|
|
19
|
-
return removed;
|
|
20
|
-
}
|
|
21
|
-
registerConnectorRegistryAdapter({ adapter: officialMcpRegistryAdapter });
|
|
22
|
-
registerConnectorRegistryAdapter({ adapter: smitheryRegistryAdapter });
|
|
23
|
-
registerConnectorRegistryAdapter({ adapter: modelscopeRegistryAdapter });
|
|
24
|
-
function cacheKey(params) {
|
|
25
|
-
return JSON.stringify({
|
|
26
|
-
source: params.source ?? "all",
|
|
27
|
-
query: params.query?.trim() ?? "",
|
|
28
|
-
page: params.page ?? 1,
|
|
29
|
-
pageSize: params.pageSize ?? 24,
|
|
30
|
-
browse: params.browse ?? false
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
function listConnectorRegistries() {
|
|
34
|
-
return [...registryAdapters.values()].map((registry) => ({
|
|
35
|
-
id: registry.source,
|
|
36
|
-
displayName: registry.displayName
|
|
37
|
-
}));
|
|
38
|
-
}
|
|
39
|
-
function isConnectorRegistrySource(source) {
|
|
40
|
-
return registryAdapters.has(source);
|
|
41
|
-
}
|
|
42
|
-
async function runRegistrySearch(params) {
|
|
43
|
-
const source = params.source ?? "all";
|
|
44
|
-
const registries = source === "all" ? [...registryAdapters.values()] : [...registryAdapters.values()].filter((registry) => registry.source === source);
|
|
45
|
-
return Promise.all(registries.map(async (registry) => {
|
|
46
|
-
try {
|
|
47
|
-
return await registry.search(params);
|
|
48
|
-
} catch (error) {
|
|
49
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
50
|
-
log.warn({
|
|
51
|
-
source: registry.source,
|
|
52
|
-
errorMessage
|
|
53
|
-
}, `Connector registry search failed: ${errorMessage}`);
|
|
54
|
-
return {
|
|
55
|
-
source: registry.source,
|
|
56
|
-
connectors: [],
|
|
57
|
-
error: errorMessage
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
}));
|
|
61
|
-
}
|
|
62
|
-
async function searchConnectorRegistries(params) {
|
|
63
|
-
if (!params.query?.trim() && !params.browse) {
|
|
64
|
-
const source = params.source ?? "all";
|
|
65
|
-
return (source === "all" ? [...registryAdapters.values()] : [...registryAdapters.values()].filter((registry) => registry.source === source)).map((registry) => ({
|
|
66
|
-
source: registry.source,
|
|
67
|
-
connectors: []
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
const key = cacheKey(params);
|
|
71
|
-
const now = Date.now();
|
|
72
|
-
const cached = registrySearchCache.get(key);
|
|
73
|
-
if (cached && cached.expiresAt > now) return cached.promise;
|
|
74
|
-
const promise = runRegistrySearch(params);
|
|
75
|
-
registrySearchCache.set(key, {
|
|
76
|
-
expiresAt: now + REGISTRY_CACHE_TTL_MS,
|
|
77
|
-
promise
|
|
78
|
-
});
|
|
79
|
-
try {
|
|
80
|
-
return await promise;
|
|
81
|
-
} catch (error) {
|
|
82
|
-
registrySearchCache.delete(key);
|
|
83
|
-
throw error;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
//#endregion
|
|
87
|
-
export { isConnectorRegistrySource, listConnectorRegistries, registerConnectorRegistryAdapter, searchConnectorRegistries, unregisterConnectorRegistryAdapter };
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
//#region src/connectors/registries/smithery.ts
|
|
2
|
-
const DEFAULT_BASE_URL = "https://registry.smithery.ai";
|
|
3
|
-
function smitheryApiKey() {
|
|
4
|
-
return process.env.XOPC_SMITHERY_API_KEY?.trim() || process.env.SMITHERY_API_KEY?.trim() || void 0;
|
|
5
|
-
}
|
|
6
|
-
function smitheryBaseUrl() {
|
|
7
|
-
return process.env.XOPC_SMITHERY_REGISTRY_URL?.trim().replace(/\/+$/, "") || DEFAULT_BASE_URL;
|
|
8
|
-
}
|
|
9
|
-
function readString(value) {
|
|
10
|
-
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
11
|
-
}
|
|
12
|
-
function slugFrom(value) {
|
|
13
|
-
return value.trim().toLowerCase().replace(/^@/, "").replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "smithery-mcp";
|
|
14
|
-
}
|
|
15
|
-
function connectorFromSmitheryServer(server, apiKey) {
|
|
16
|
-
const qualifiedName = readString(server.qualifiedName ?? server.qualified_name ?? server.name ?? server.id);
|
|
17
|
-
const displayName = readString(server.displayName ?? server.display_name ?? server.name) ?? qualifiedName;
|
|
18
|
-
if (!qualifiedName || !displayName) return void 0;
|
|
19
|
-
const serverId = slugFrom(qualifiedName);
|
|
20
|
-
const url = `https://server.smithery.ai/${qualifiedName.split("/").map((part) => encodeURIComponent(part)).join("/")}/mcp`;
|
|
21
|
-
const headers = apiKey ? { Authorization: `Bearer ${apiKey}` } : void 0;
|
|
22
|
-
return {
|
|
23
|
-
id: `smithery-${serverId}`,
|
|
24
|
-
version: readString(server.version) ?? "registry",
|
|
25
|
-
displayName,
|
|
26
|
-
description: readString(server.description) ?? "MCP server hosted through Smithery.",
|
|
27
|
-
category: "custom",
|
|
28
|
-
kind: "mcp",
|
|
29
|
-
source: "registry",
|
|
30
|
-
capabilities: apiKey ? [
|
|
31
|
-
"tools",
|
|
32
|
-
"resources",
|
|
33
|
-
"prompts",
|
|
34
|
-
"auth.apiKey",
|
|
35
|
-
"runtime.mcp.streamableHttp"
|
|
36
|
-
] : [
|
|
37
|
-
"tools",
|
|
38
|
-
"resources",
|
|
39
|
-
"prompts",
|
|
40
|
-
"runtime.mcp.streamableHttp"
|
|
41
|
-
],
|
|
42
|
-
tags: [
|
|
43
|
-
"smithery",
|
|
44
|
-
"registry",
|
|
45
|
-
"mcp"
|
|
46
|
-
],
|
|
47
|
-
auth: { mode: apiKey ? "apiKey" : "none" },
|
|
48
|
-
setup: {},
|
|
49
|
-
runtime: {
|
|
50
|
-
type: "mcp",
|
|
51
|
-
serverId,
|
|
52
|
-
serverTemplate: {
|
|
53
|
-
url,
|
|
54
|
-
transport: "streamable-http",
|
|
55
|
-
...headers ? { headers } : {}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
function extractServers(payload) {
|
|
61
|
-
if (Array.isArray(payload)) return payload.filter((item) => Boolean(item && typeof item === "object" && !Array.isArray(item)));
|
|
62
|
-
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return [];
|
|
63
|
-
const data = payload;
|
|
64
|
-
for (const key of [
|
|
65
|
-
"servers",
|
|
66
|
-
"items",
|
|
67
|
-
"results",
|
|
68
|
-
"data"
|
|
69
|
-
]) {
|
|
70
|
-
const value = data[key];
|
|
71
|
-
if (Array.isArray(value)) return value.filter((item) => Boolean(item && typeof item === "object" && !Array.isArray(item)));
|
|
72
|
-
}
|
|
73
|
-
return [];
|
|
74
|
-
}
|
|
75
|
-
const smitheryRegistryAdapter = {
|
|
76
|
-
source: "smithery",
|
|
77
|
-
displayName: "Smithery",
|
|
78
|
-
async search(params) {
|
|
79
|
-
const apiKey = smitheryApiKey();
|
|
80
|
-
const url = new URL("/servers", smitheryBaseUrl());
|
|
81
|
-
const query = params.query?.trim();
|
|
82
|
-
if (query) url.searchParams.set("q", query);
|
|
83
|
-
url.searchParams.set("pageSize", String(Math.min(Math.max(params.pageSize ?? 24, 1), 100)));
|
|
84
|
-
if (params.page && params.page > 1) url.searchParams.set("page", String(params.page));
|
|
85
|
-
const response = await fetch(url, { headers: {
|
|
86
|
-
Accept: "application/json",
|
|
87
|
-
...apiKey ? { Authorization: `Bearer ${apiKey}` } : {}
|
|
88
|
-
} });
|
|
89
|
-
if (!response.ok) throw new Error(`Smithery registry returned ${response.status}`);
|
|
90
|
-
return {
|
|
91
|
-
source: "smithery",
|
|
92
|
-
connectors: extractServers(await response.json()).map((server) => connectorFromSmitheryServer(server, apiKey)).filter((item) => Boolean(item))
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
//#endregion
|
|
97
|
-
export { smitheryRegistryAdapter };
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { ConnectorDefinition } from '../types.js';
|
|
2
|
-
export type ConnectorRegistrySource = string;
|
|
3
|
-
export type ConnectorRegistrySearchParams = {
|
|
4
|
-
query?: string;
|
|
5
|
-
page?: number;
|
|
6
|
-
pageSize?: number;
|
|
7
|
-
source?: ConnectorRegistrySource | 'all';
|
|
8
|
-
browse?: boolean;
|
|
9
|
-
};
|
|
10
|
-
export type ConnectorRegistrySearchResult = {
|
|
11
|
-
source: ConnectorRegistrySource;
|
|
12
|
-
connectors: ConnectorDefinition[];
|
|
13
|
-
totalPages?: number;
|
|
14
|
-
error?: string;
|
|
15
|
-
};
|
|
16
|
-
export type ConnectorRegistryAdapter = {
|
|
17
|
-
source: ConnectorRegistrySource;
|
|
18
|
-
displayName: string;
|
|
19
|
-
search(params: ConnectorRegistrySearchParams): Promise<ConnectorRegistrySearchResult>;
|
|
20
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|