clay-server 2.28.0-beta.1 → 2.28.0-beta.3

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/lib/sdk-bridge.js CHANGED
@@ -10,6 +10,31 @@ var { splitShellSegments, attachSkillDiscovery } = require("./sdk-skill-discover
10
10
  var { createMessageQueue } = require("./sdk-message-queue");
11
11
  var { attachMessageProcessor } = require("./sdk-message-processor");
12
12
 
13
+ // Merge in-process MCP servers with remote (extension-bridged) MCP servers.
14
+ // Returns the merged object, or null if no servers exist.
15
+ function mergeMcpServers(localServers, getRemoteFn) {
16
+ var merged = {};
17
+ var hasAny = false;
18
+ if (localServers) {
19
+ var lk = Object.keys(localServers);
20
+ for (var i = 0; i < lk.length; i++) {
21
+ merged[lk[i]] = localServers[lk[i]];
22
+ hasAny = true;
23
+ }
24
+ }
25
+ if (typeof getRemoteFn === "function") {
26
+ var remote = getRemoteFn();
27
+ if (remote) {
28
+ var rk = Object.keys(remote);
29
+ for (var j = 0; j < rk.length; j++) {
30
+ merged[rk[j]] = remote[rk[j]];
31
+ hasAny = true;
32
+ }
33
+ }
34
+ }
35
+ return hasAny ? merged : null;
36
+ }
37
+
13
38
  function createSDKBridge(opts) {
14
39
  var cwd = opts.cwd;
15
40
  var slug = opts.slug || "";
@@ -22,6 +47,7 @@ function createSDKBridge(opts) {
22
47
  var isMate = opts.isMate || (slug.indexOf("mate-") === 0);
23
48
  var dangerouslySkipPermissions = opts.dangerouslySkipPermissions || false;
24
49
  var mcpServers = opts.mcpServers || null;
50
+ var getRemoteMcpServers = opts.getRemoteMcpServers || null;
25
51
  var onProcessingChanged = opts.onProcessingChanged || function () {};
26
52
  var onTurnDone = opts.onTurnDone || null;
27
53
 
@@ -553,7 +579,8 @@ function createSDKBridge(opts) {
553
579
  agentProgressSummaries: true,
554
580
  };
555
581
 
556
- if (mcpServers) queryOptions.mcpServers = mcpServers;
582
+ var _mergedMcp = mergeMcpServers(mcpServers, getRemoteMcpServers);
583
+ if (_mergedMcp) queryOptions.mcpServers = _mergedMcp;
557
584
 
558
585
  // Per-loop settings override global defaults when present
559
586
  var ls2 = session.loopSettings || {};
@@ -930,7 +957,7 @@ function createSDKBridge(opts) {
930
957
  return;
931
958
  }
932
959
 
933
- var warmupOptions = { cwd: cwd, settingSources: ["user", "project", "local"] };
960
+ var warmupOptions = { cwd: cwd, settingSources: ["user", "project", "local"], settings: { disableAllHooks: true } };
934
961
  if (dangerouslySkipPermissions) {
935
962
  warmupOptions.permissionMode = "bypassPermissions";
936
963
  warmupOptions.allowDangerouslySkipPermissions = true;
@@ -970,6 +997,19 @@ function createSDKBridge(opts) {
970
997
  return { behavior: "allow", updatedInput: input };
971
998
  }
972
999
 
1000
+ // Auto-approve remote MCP tools that the user explicitly enabled in project settings.
1001
+ // These are user-owned local MCP servers, so no additional permission prompt needed.
1002
+ if (toolName.indexOf("mcp__") === 0 && getRemoteMcpServers) {
1003
+ var _rmcp = getRemoteMcpServers();
1004
+ if (_rmcp) {
1005
+ var _mcpParts = toolName.split("__");
1006
+ var _mcpServerName = _mcpParts.length >= 2 ? _mcpParts[1] : "";
1007
+ if (_rmcp[_mcpServerName]) {
1008
+ return { behavior: "allow", updatedInput: input };
1009
+ }
1010
+ }
1011
+ }
1012
+
973
1013
  // Auto-approve safe Bash commands (read-only, non-destructive)
974
1014
  // Applies to ALL sessions (mates and regular projects alike).
975
1015
  // These are purely read-only commands that cannot modify files, install
@@ -1440,7 +1480,7 @@ function createSDKBridge(opts) {
1440
1480
  abortController: session.abortController,
1441
1481
  promptSuggestions: true,
1442
1482
  agentProgressSummaries: true,
1443
- mcpServers: mcpServers || undefined,
1483
+ mcpServers: mergeMcpServers(mcpServers, getRemoteMcpServers) || undefined,
1444
1484
  canUseTool: function(toolName, input, toolOpts) {
1445
1485
  return handleCanUseTool(session, toolName, input, toolOpts);
1446
1486
  },
@@ -1617,7 +1657,7 @@ function createSDKBridge(opts) {
1617
1657
  var mq = createMessageQueue();
1618
1658
  mq.push({ type: "user", message: { role: "user", content: [{ type: "text", text: "hi" }] } });
1619
1659
  mq.end();
1620
- var warmupOptions = { cwd: cwd, settingSources: ["user", "project", "local"], abortController: ac };
1660
+ var warmupOptions = { cwd: cwd, settingSources: ["user", "project", "local"], abortController: ac, settings: { disableAllHooks: true } };
1621
1661
  if (dangerouslySkipPermissions) {
1622
1662
  warmupOptions.permissionMode = "bypassPermissions";
1623
1663
  warmupOptions.allowDangerouslySkipPermissions = true;
@@ -1789,7 +1829,10 @@ function createSDKBridge(opts) {
1789
1829
  },
1790
1830
  };
1791
1831
  if (opts.model) mentionQueryOptions.model = opts.model;
1792
- if (opts.includeMcpServers && mcpServers) mentionQueryOptions.mcpServers = mcpServers;
1832
+ if (opts.includeMcpServers) {
1833
+ var _mentionMcp = mergeMcpServers(mcpServers, getRemoteMcpServers);
1834
+ if (_mentionMcp) mentionQueryOptions.mcpServers = _mentionMcp;
1835
+ }
1793
1836
  query = sdk.query({
1794
1837
  prompt: mq,
1795
1838
  options: mentionQueryOptions,
package/lib/server.js CHANGED
@@ -144,6 +144,8 @@ function createServer(opts) {
144
144
  var onSetServerDefaultMode = opts.onSetServerDefaultMode || null;
145
145
  var onGetProjectDefaultMode = opts.onGetProjectDefaultMode || null;
146
146
  var onSetProjectDefaultMode = opts.onSetProjectDefaultMode || null;
147
+ var onGetProjectMcpServers = opts.onGetProjectMcpServers || null;
148
+ var onSetProjectMcpServers = opts.onSetProjectMcpServers || null;
147
149
  var onGetDaemonConfig = opts.onGetDaemonConfig || null;
148
150
  var onSetPin = opts.onSetPin || null;
149
151
  var onSetKeepAwake = opts.onSetKeepAwake || null;
@@ -766,6 +768,8 @@ function createServer(opts) {
766
768
  return origEmit.apply(ws, arguments);
767
769
  };
768
770
  ws._clayUser = wsUser; // attach user context
771
+ var remoteAddr = req.socket.remoteAddress || "";
772
+ ws._clayLocal = (remoteAddr === "127.0.0.1" || remoteAddr === "::1" || remoteAddr === "::ffff:127.0.0.1");
769
773
  // Clear cross-project unread for this project when client connects
770
774
  var unreadMap = getCrossProjectUnread(ws);
771
775
  if (unreadMap[wsSlug]) {
@@ -984,6 +988,8 @@ function createServer(opts) {
984
988
  onSetServerDefaultMode: onSetServerDefaultMode,
985
989
  onGetProjectDefaultMode: onGetProjectDefaultMode,
986
990
  onSetProjectDefaultMode: onSetProjectDefaultMode,
991
+ onGetProjectMcpServers: onGetProjectMcpServers,
992
+ onSetProjectMcpServers: onSetProjectMcpServers,
987
993
  onGetDaemonConfig: onGetDaemonConfig,
988
994
  onSetPin: onSetPin,
989
995
  onSetKeepAwake: onSetKeepAwake,
package/lib/ws-schema.js CHANGED
@@ -338,6 +338,16 @@ var schema = {
338
338
  "clay_ext_result": { direction: "s2c", handler: "lib/public/modules/app-misc.js", description: "Browser extension command result (broadcast)" },
339
339
  "clay_ext_command": { direction: "c2s", handler: "lib/public/modules/app-misc.js", description: "Send a command to the browser extension" },
340
340
 
341
+ // -----------------------------------------------------------------------
342
+ // MCP Bridge (remote MCP servers via Chrome Extension)
343
+ // -----------------------------------------------------------------------
344
+ "mcp_servers_available": { direction: "c2s", handler: "lib/project-mcp.js", description: "Report available MCP servers from Chrome Extension" },
345
+ "mcp_tool_call": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Forward MCP tool call to extension or HTTP endpoint" },
346
+ "mcp_tool_result": { direction: "c2s", handler: "lib/project-mcp.js", description: "Return MCP tool result from extension" },
347
+ "mcp_tool_error": { direction: "c2s", handler: "lib/project-mcp.js", description: "Return MCP tool error from extension" },
348
+ "mcp_toggle_server": { direction: "c2s", handler: "lib/project-mcp.js", description: "Toggle MCP server enabled state for this project" },
349
+ "mcp_servers_state": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Broadcast MCP server list and enabled state to clients" },
350
+
341
351
  // -----------------------------------------------------------------------
342
352
  // Skills
343
353
  // -----------------------------------------------------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "2.28.0-beta.1",
3
+ "version": "2.28.0-beta.3",
4
4
  "description": "Self-hosted Claude Code in your browser. Multi-session, multi-user, push notifications.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",