promethios-bridge 2.1.4 → 2.1.6
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/package.json +1 -1
- package/src/bridge.js +87 -2
- package/src/mcp-catalog.json +896 -0
- package/src/mcp-registry.js +397 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "promethios-bridge",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6",
|
|
4
4
|
"description": "Run Promethios agent frameworks locally on your computer with full file, terminal, browser access, ambient context capture, and the always-on-top floating chat overlay. Native Framework Mode supports OpenClaw and other frameworks via the bridge.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
package/src/bridge.js
CHANGED
|
@@ -21,7 +21,8 @@ const ora = require('ora');
|
|
|
21
21
|
const fetch = require('node-fetch');
|
|
22
22
|
const { executeLocalTool } = require('./executor');
|
|
23
23
|
const { captureContext } = require('./contextCapture');
|
|
24
|
-
const { startMcpServer } = require('./mcp-server');
|
|
24
|
+
const { startMcpServer, FULL_MANIFEST } = require('./mcp-server');
|
|
25
|
+
const mcpRegistry = require('./mcp-registry');
|
|
25
26
|
const { setPinnedRegion, setPinnedApps, registerBrowserPageAccessor } = require('./tools/desktop');
|
|
26
27
|
|
|
27
28
|
// Wire the browser-dom tools to the shared Playwright context.
|
|
@@ -236,6 +237,85 @@ async function startBridge({ setupToken, apiBase, port, dev }) {
|
|
|
236
237
|
res.json({ status: 'ok', url });
|
|
237
238
|
});
|
|
238
239
|
|
|
240
|
+
// ── /mcp/* ── MCP Marketplace endpoints ────────────────────────────────────────────
|
|
241
|
+
// All /mcp/* endpoints are localhost-only (no auth token required).
|
|
242
|
+
// They are called by the Promethios web app marketplace UI.
|
|
243
|
+
|
|
244
|
+
// GET /mcp/catalog — serve the curated marketplace catalog
|
|
245
|
+
app.get('/mcp/catalog', (req, res) => {
|
|
246
|
+
try {
|
|
247
|
+
const catalog = require('./mcp-catalog.json');
|
|
248
|
+
const installed = mcpRegistry.listInstalled();
|
|
249
|
+
const installedIds = new Set(installed.map(e => e.id));
|
|
250
|
+
const enriched = catalog.map(item => ({ ...item, installed: installedIds.has(item.id) }));
|
|
251
|
+
res.json({ ok: true, catalog: enriched });
|
|
252
|
+
} catch (err) {
|
|
253
|
+
res.status(500).json({ error: err.message });
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// GET /mcp/list — list all installed MCP servers (built-ins + user-installed)
|
|
258
|
+
app.get('/mcp/list', (req, res) => {
|
|
259
|
+
const all = mcpRegistry.listAll();
|
|
260
|
+
res.json({ ok: true, servers: all });
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// GET /mcp/tools — aggregated tool list from all running MCP servers
|
|
264
|
+
// Also includes the built-in Promethios desktop + android tools.
|
|
265
|
+
app.get('/mcp/tools', (req, res) => {
|
|
266
|
+
const builtinTools = FULL_MANIFEST.map(t => ({ ...t, _mcpServerId: 'promethios-desktop' }));
|
|
267
|
+
const installedTools = mcpRegistry.getAggregatedTools();
|
|
268
|
+
res.json({ ok: true, tools: [...builtinTools, ...installedTools] });
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// POST /mcp/install — install an MCP server from the marketplace
|
|
272
|
+
// Body: { id, name, package, description, icon, env, args }
|
|
273
|
+
app.post('/mcp/install', async (req, res) => {
|
|
274
|
+
const { id, name, package: pkg, description, icon, env, args } = req.body || {};
|
|
275
|
+
if (!id || !pkg) return res.status(400).json({ error: 'id and package are required' });
|
|
276
|
+
if (mcpRegistry.isInstalled(id)) {
|
|
277
|
+
return res.status(409).json({ error: `${id} is already installed` });
|
|
278
|
+
}
|
|
279
|
+
log(`[mcp-marketplace] Installing ${pkg}...`);
|
|
280
|
+
const result = await mcpRegistry.npmInstall(pkg);
|
|
281
|
+
if (!result.ok) {
|
|
282
|
+
return res.status(500).json({ error: 'npm install failed', detail: result.error });
|
|
283
|
+
}
|
|
284
|
+
const entry = { id, name, package: pkg, version: result.version, description, icon, env: env || {}, args: args || [] };
|
|
285
|
+
mcpRegistry.addEntry(entry);
|
|
286
|
+
// Start the server immediately so tools are available right away
|
|
287
|
+
try {
|
|
288
|
+
const tools = await mcpRegistry.startServer(entry, log);
|
|
289
|
+
return res.json({ ok: true, id, version: result.version, toolCount: tools.length });
|
|
290
|
+
} catch (err) {
|
|
291
|
+
return res.json({ ok: true, id, version: result.version, toolCount: 0, warning: 'Installed but failed to start: ' + err.message });
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// DELETE /mcp/uninstall — uninstall an MCP server
|
|
296
|
+
// Body: { id }
|
|
297
|
+
app.delete('/mcp/uninstall', async (req, res) => {
|
|
298
|
+
const { id } = req.body || {};
|
|
299
|
+
if (!id) return res.status(400).json({ error: 'id is required' });
|
|
300
|
+
const entry = mcpRegistry.getById(id);
|
|
301
|
+
if (!entry) return res.status(404).json({ error: `${id} not found` });
|
|
302
|
+
mcpRegistry.stopServer(id);
|
|
303
|
+
const uninstallResult = await mcpRegistry.npmUninstall(entry.package);
|
|
304
|
+
mcpRegistry.removeEntry(id);
|
|
305
|
+
res.json({ ok: true, id, npmResult: uninstallResult });
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// PATCH /mcp/toggle — enable or disable an installed MCP server
|
|
309
|
+
// Body: { id, enabled }
|
|
310
|
+
app.patch('/mcp/toggle', (req, res) => {
|
|
311
|
+
const { id, enabled } = req.body || {};
|
|
312
|
+
if (!id || typeof enabled !== 'boolean') return res.status(400).json({ error: 'id and enabled (boolean) required' });
|
|
313
|
+
if (!mcpRegistry.isInstalled(id)) return res.status(404).json({ error: `${id} not found` });
|
|
314
|
+
mcpRegistry.setEnabled(id, enabled);
|
|
315
|
+
if (!enabled) mcpRegistry.stopServer(id);
|
|
316
|
+
res.json({ ok: true, id, enabled });
|
|
317
|
+
});
|
|
318
|
+
|
|
239
319
|
// ── /status: used by the Electron overlay to auto-connect without manual token entry ──
|
|
240
320
|
// Only accessible from localhost (127.0.0.1 or ::1) for security.
|
|
241
321
|
let bridgeUsername = null; // set after registerBridge resolves
|
|
@@ -844,7 +924,12 @@ async function startBridge({ setupToken, apiBase, port, dev }) {
|
|
|
844
924
|
process.exit(1);
|
|
845
925
|
}
|
|
846
926
|
|
|
847
|
-
// ── Step 3b:
|
|
927
|
+
// // ── Step 3b: Start installed MCP servers (non-blocking) ───────────────────
|
|
928
|
+
mcpRegistry.startAllEnabled(log).catch(err => {
|
|
929
|
+
log('[mcp-registry] startAllEnabled error:', err.message);
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
// ── Step 3c: Check for updates (non-blocking) ───────────────────────
|
|
848
933
|
const currentVersion = require('../package.json').version;
|
|
849
934
|
checkForUpdates(currentVersion, log).catch(() => {}); // fire-and-forget
|
|
850
935
|
|