@cjhyy/code-shell-core 0.9.5 → 0.9.7
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/automation/scheduler.d.ts +3 -0
- package/dist/automation/scheduler.js +21 -0
- package/dist/context/manager.d.ts +8 -2
- package/dist/context/manager.js +20 -4
- package/dist/context/notes.d.ts +39 -0
- package/dist/context/notes.js +314 -0
- package/dist/credentials/access.d.ts +9 -1
- package/dist/credentials/access.js +15 -4
- package/dist/credentials/store.d.ts +11 -0
- package/dist/credentials/store.js +44 -9
- package/dist/credentials/types.d.ts +4 -0
- package/dist/credentials/types.js +4 -0
- package/dist/credentials/use-credential-tool.js +12 -2
- package/dist/engine/engine-workspace-authority.js +10 -3
- package/dist/engine/engine.d.ts +8 -4
- package/dist/engine/engine.js +115 -15
- package/dist/engine/prompt-cache-diagnostics.js +10 -1
- package/dist/engine/run-goal.js +7 -3
- package/dist/engine/run-tooling.d.ts +3 -0
- package/dist/engine/run-tooling.js +25 -23
- package/dist/engine/run-types.d.ts +20 -0
- package/dist/engine/run-workspace.js +5 -21
- package/dist/engine/subagent-spawner.d.ts +3 -0
- package/dist/engine/subagent-spawner.js +48 -17
- package/dist/engine/turn-loop.d.ts +14 -4
- package/dist/engine/turn-loop.js +120 -28
- package/dist/engine/types.d.ts +19 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/links/index.d.ts +1 -0
- package/dist/links/index.js +1 -0
- package/dist/links/link-action-tool.d.ts +2 -1
- package/dist/links/link-action-tool.js +80 -44
- package/dist/links/status.d.ts +53 -0
- package/dist/links/status.js +175 -0
- package/dist/llm/prompt-cache.d.ts +35 -3
- package/dist/llm/prompt-cache.js +63 -3
- package/dist/llm/providers/openai.d.ts +3 -0
- package/dist/llm/providers/openai.js +57 -14
- package/dist/prompt/section-loader.js +1 -0
- package/dist/prompt/sections/browser.md +4 -2
- package/dist/prompt/sections/context-notes.md +9 -0
- package/dist/protocol/background-result-wakeup.d.ts +8 -1
- package/dist/protocol/background-result-wakeup.js +76 -38
- package/dist/protocol/chat-session-manager.d.ts +7 -1
- package/dist/protocol/chat-session-manager.js +44 -8
- package/dist/protocol/chat-session.d.ts +2 -0
- package/dist/protocol/chat-session.js +4 -1
- package/dist/protocol/server.d.ts +4 -0
- package/dist/protocol/server.js +355 -62
- package/dist/protocol/session-message-result.d.ts +12 -0
- package/dist/protocol/session-message-result.js +42 -0
- package/dist/protocol/session-message-workspace.d.ts +21 -0
- package/dist/protocol/session-message-workspace.js +57 -0
- package/dist/protocol/types.d.ts +4 -0
- package/dist/session/session-manager.js +8 -7
- package/dist/session/session-message.d.ts +17 -2
- package/dist/session/transcript.d.ts +17 -0
- package/dist/session/transcript.js +271 -16
- package/dist/settings/schema.d.ts +9 -0
- package/dist/settings/schema.js +4 -0
- package/dist/themes/paths.js +20 -1
- package/dist/tool-system/browser-bridge.d.ts +21 -1
- package/dist/tool-system/browser-discovery.d.ts +6 -0
- package/dist/tool-system/browser-discovery.js +17 -0
- package/dist/tool-system/builtin/agent.js +23 -9
- package/dist/tool-system/builtin/browser-tools.js +30 -9
- package/dist/tool-system/builtin/context-notes.d.ts +12 -0
- package/dist/tool-system/builtin/context-notes.js +188 -0
- package/dist/tool-system/builtin/index.js +50 -3
- package/dist/tool-system/builtin/mcp-tools.d.ts +5 -3
- package/dist/tool-system/builtin/mcp-tools.js +10 -10
- package/dist/tool-system/builtin/send-message-to-session.js +19 -3
- package/dist/tool-system/builtin/tool-search.js +15 -3
- package/dist/tool-system/context.d.ts +9 -0
- package/dist/tool-system/executor.js +5 -3
- package/dist/tool-system/mcp-compat.d.ts +3 -0
- package/dist/tool-system/mcp-compat.js +51 -0
- package/dist/tool-system/mcp-manager.d.ts +27 -26
- package/dist/tool-system/mcp-manager.js +273 -111
- package/dist/tool-system/mcp-workspace.d.ts +18 -0
- package/dist/tool-system/mcp-workspace.js +56 -0
- package/dist/tool-system/permission.d.ts +6 -0
- package/dist/tool-system/permission.js +45 -9
- package/dist/tool-system/plan-mode-allowlist.js +5 -0
- package/dist/tool-system/sandbox/seatbelt.js +71 -2
- package/dist/tool-system/session-tool-host.js +9 -1
- package/dist/types.d.ts +4 -2
- package/package.json +1 -1
|
@@ -24,7 +24,7 @@ export const mcpToolDef = {
|
|
|
24
24
|
required: ["server", "tool"],
|
|
25
25
|
},
|
|
26
26
|
};
|
|
27
|
-
export async function mcpToolExecute(args) {
|
|
27
|
+
export async function mcpToolExecute(args, ctx) {
|
|
28
28
|
const server = args.server;
|
|
29
29
|
const tool = args.tool;
|
|
30
30
|
const toolArgs = args.arguments ?? {};
|
|
@@ -33,12 +33,12 @@ export async function mcpToolExecute(args) {
|
|
|
33
33
|
const signal = args.__signal;
|
|
34
34
|
try {
|
|
35
35
|
const { MCPManager } = await import("../mcp-manager.js");
|
|
36
|
-
const manager = MCPManager.
|
|
37
|
-
const result = await manager.callTool(server, tool, toolArgs, signal);
|
|
36
|
+
const manager = MCPManager.forContext(ctx);
|
|
37
|
+
const result = await manager.callTool(server, tool, toolArgs, signal, ctx);
|
|
38
38
|
return typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
39
39
|
}
|
|
40
40
|
catch (err) {
|
|
41
|
-
return `MCP tool error: ${err.message}
|
|
41
|
+
return { ok: false, error: `MCP tool error: ${err.message}` };
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
// ─── ListMcpResources — list available MCP resources ────────────
|
|
@@ -55,7 +55,7 @@ export const listMcpResourcesToolDef = {
|
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
57
|
};
|
|
58
|
-
export async function listMcpResourcesTool(args) {
|
|
58
|
+
export async function listMcpResourcesTool(args, ctx) {
|
|
59
59
|
const server = args.server ?? "";
|
|
60
60
|
// The executor injects the session's allowed-server set (see executor.ts).
|
|
61
61
|
// When no explicit server filter is given, we must only enumerate resources
|
|
@@ -64,11 +64,11 @@ export async function listMcpResourcesTool(args) {
|
|
|
64
64
|
const allowed = args.__allowedMcpServers;
|
|
65
65
|
try {
|
|
66
66
|
const { MCPManager } = await import("../mcp-manager.js");
|
|
67
|
-
const manager = MCPManager.
|
|
67
|
+
const manager = MCPManager.forContext(ctx);
|
|
68
68
|
// Forward the run's abort signal (registry injects __signal) so Stop cancels
|
|
69
69
|
// promptly instead of waiting out the SDK's default request timeout.
|
|
70
70
|
const signal = args.__signal;
|
|
71
|
-
let resources = await manager.listResources(server || undefined, signal);
|
|
71
|
+
let resources = await manager.listResources(server || undefined, signal, ctx);
|
|
72
72
|
if (allowed && resources) {
|
|
73
73
|
resources = resources.filter((r) => {
|
|
74
74
|
// Resource entries may carry the owning server on `serverName`/`server`;
|
|
@@ -106,14 +106,14 @@ export const readMcpResourceToolDef = {
|
|
|
106
106
|
required: ["server", "uri"],
|
|
107
107
|
},
|
|
108
108
|
};
|
|
109
|
-
export async function readMcpResourceTool(args) {
|
|
109
|
+
export async function readMcpResourceTool(args, ctx) {
|
|
110
110
|
const server = args.server;
|
|
111
111
|
const uri = args.uri;
|
|
112
112
|
try {
|
|
113
113
|
const { MCPManager } = await import("../mcp-manager.js");
|
|
114
|
-
const manager = MCPManager.
|
|
114
|
+
const manager = MCPManager.forContext(ctx);
|
|
115
115
|
const signal = args.__signal;
|
|
116
|
-
const content = await manager.readResource(server, uri, signal);
|
|
116
|
+
const content = await manager.readResource(server, uri, signal, ctx);
|
|
117
117
|
return typeof content === "string" ? content : JSON.stringify(content, null, 2);
|
|
118
118
|
}
|
|
119
119
|
catch (err) {
|
|
@@ -3,7 +3,9 @@ export const sendMessageToSessionToolDef = {
|
|
|
3
3
|
name: SEND_MESSAGE_TO_SESSION_TOOL_NAME,
|
|
4
4
|
description: "Send a message to another host-authorized Session in the current project. " +
|
|
5
5
|
"Use this exactly like a person sending a message in that Session: the message becomes the target Session's next user turn and queues or starts its work. " +
|
|
6
|
-
"
|
|
6
|
+
"The result reports whether this turn is queued, started, or already completed. " +
|
|
7
|
+
"For queued or started turns, that turn's answer or failure is returned to this Session automatically; do not poll by sending the task again. " +
|
|
8
|
+
"When you have later additions, call this tool again with another message. This does not subscribe to unrelated future target turns.",
|
|
7
9
|
inputSchema: {
|
|
8
10
|
type: "object",
|
|
9
11
|
properties: {
|
|
@@ -54,8 +56,22 @@ export async function sendMessageToSessionTool(args, ctx) {
|
|
|
54
56
|
if (message.length > 48_000)
|
|
55
57
|
return "Error: message exceeds 48000 characters.";
|
|
56
58
|
try {
|
|
57
|
-
const target = await service.send({
|
|
58
|
-
|
|
59
|
+
const target = await service.send({
|
|
60
|
+
targetSessionId,
|
|
61
|
+
message,
|
|
62
|
+
...(ctx?.signal ? { signal: ctx.signal } : {}),
|
|
63
|
+
});
|
|
64
|
+
const receipt = target.receipt;
|
|
65
|
+
const label = `"${target.title}" (${target.sessionId})`;
|
|
66
|
+
if (!receipt) {
|
|
67
|
+
// Compatibility with custom hosts that implement the original router.
|
|
68
|
+
return `Message accepted by ${label}. This host did not provide execution status or automatic reply delivery.`;
|
|
69
|
+
}
|
|
70
|
+
if (receipt.status === "completed") {
|
|
71
|
+
return `Message ${receipt.messageId} completed in ${label}.\n\n${receipt.result?.text ?? ""}`;
|
|
72
|
+
}
|
|
73
|
+
const status = receipt.status === "started" ? "started" : "queued (not yet confirmed started)";
|
|
74
|
+
return `Message ${receipt.messageId} accepted by ${label}; status: ${status}. This turn's answer or failure will be returned to this Session automatically.`;
|
|
59
75
|
}
|
|
60
76
|
catch (error) {
|
|
61
77
|
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* saving context by not loading all MCP tool schemas upfront.
|
|
7
7
|
*/
|
|
8
8
|
import { isRegisteredMcpToolAllowed } from "../mcp-tool-policy.js";
|
|
9
|
+
import { browserDiscoveryScore, isBuiltinBrowserTool } from "../browser-discovery.js";
|
|
10
|
+
import { PLAN_MODE_ALLOWED_TOOLS } from "../plan-mode-allowlist.js";
|
|
9
11
|
export const toolSearchToolDef = {
|
|
10
12
|
name: "ToolSearch",
|
|
11
13
|
description: "Search only the tools available in the current Session context by name or keyword. " +
|
|
@@ -59,8 +61,18 @@ export async function toolSearchTool(args, ctx) {
|
|
|
59
61
|
// its server is in this session's allowedMcpServers. Undefined set = no
|
|
60
62
|
// gating (sub-agents / hosts that don't populate it).
|
|
61
63
|
const visible = (tool) => {
|
|
62
|
-
if (tool.
|
|
63
|
-
return
|
|
64
|
+
if (ctx.disabledBuiltins?.has(tool.name))
|
|
65
|
+
return false;
|
|
66
|
+
if (ctx.allowedToolNames && !ctx.allowedToolNames.has(tool.name))
|
|
67
|
+
return false;
|
|
68
|
+
if (ctx.planMode && !PLAN_MODE_ALLOWED_TOOLS.has(tool.name))
|
|
69
|
+
return false;
|
|
70
|
+
if (tool.source !== "mcp") {
|
|
71
|
+
if (isBuiltinBrowserTool(tool) && !ctx.browser)
|
|
72
|
+
return false;
|
|
73
|
+
const guard = ctx.toolRegistry.getAvailabilityGuard(tool.name);
|
|
74
|
+
return !guard || !ctx.toolVisibility || guard(ctx.toolVisibility);
|
|
75
|
+
}
|
|
64
76
|
const allowed = ctx.allowedMcpServers;
|
|
65
77
|
return ((!allowed || allowed.has(tool.serverName ?? "")) &&
|
|
66
78
|
isRegisteredMcpToolAllowed(tool, ctx.mcpToolPolicies));
|
|
@@ -124,7 +136,7 @@ function searchDetailedTools(allTools, query, maxResults) {
|
|
|
124
136
|
const keywords = queryLower.split(/\s+/);
|
|
125
137
|
// Score each tool
|
|
126
138
|
const scored = allTools.map((tool) => {
|
|
127
|
-
let score =
|
|
139
|
+
let score = browserDiscoveryScore(tool, query);
|
|
128
140
|
const nameLower = tool.name.toLowerCase();
|
|
129
141
|
const descLower = tool.description.toLowerCase();
|
|
130
142
|
for (const kw of keywords) {
|
|
@@ -23,6 +23,7 @@ import type { SessionWorkspace } from "../types.js";
|
|
|
23
23
|
import type { ApprovalRouter } from "./permission.js";
|
|
24
24
|
import type { ChildWriterLease, LiveChildControl } from "./builtin/agent-registry.js";
|
|
25
25
|
import type { McpToolPolicy } from "./mcp-tool-policy.js";
|
|
26
|
+
import type { SessionContextNotes } from "../context/notes.js";
|
|
26
27
|
/**
|
|
27
28
|
* Narrow view of the owning Engine that tools are allowed to call back into.
|
|
28
29
|
* Defined here (in the low-level tool-system) rather than importing the
|
|
@@ -189,12 +190,16 @@ export interface SubAgentSpawnResult {
|
|
|
189
190
|
*/
|
|
190
191
|
export interface ToolVisibilityContext {
|
|
191
192
|
cwd: string;
|
|
193
|
+
/** Resolved native context strategy; omitted for external runtimes. */
|
|
194
|
+
contextStrategy?: "summary" | "notes";
|
|
192
195
|
workspace?: import("../workspace/workspace-context.js").WorkspaceContext;
|
|
193
196
|
hasGoal: boolean;
|
|
194
197
|
/** Resolved Session identity for per-session extension-tool visibility. */
|
|
195
198
|
sessionId?: string;
|
|
196
199
|
settingsScope?: import("../settings/manager.js").SettingsScope;
|
|
197
200
|
host?: string;
|
|
201
|
+
/** A browser bridge is wired for this run, independent of the host's name. */
|
|
202
|
+
hasBrowserAutomation?: boolean;
|
|
198
203
|
isSubAgent?: boolean;
|
|
199
204
|
behaviorProfile?: string;
|
|
200
205
|
/** Host-authorized targets available to the cross-Session messaging builtin. */
|
|
@@ -231,6 +236,10 @@ export interface ToolRunYieldController {
|
|
|
231
236
|
export interface ToolContext {
|
|
232
237
|
/** Active working directory for this Engine. */
|
|
233
238
|
cwd: string;
|
|
239
|
+
/** Resolved strategy for the current session's model context. */
|
|
240
|
+
contextStrategy?: "summary" | "notes";
|
|
241
|
+
/** Session-local working notes and history; never a cross-session memory store. */
|
|
242
|
+
contextNotes?: Pick<SessionContextNotes, "save" | "requestRollover" | "search" | "read">;
|
|
234
243
|
/**
|
|
235
244
|
* True when this call belongs to an external Agent Runtime rather than the
|
|
236
245
|
* native Engine loop.
|
|
@@ -409,14 +409,16 @@ export class ToolExecutor {
|
|
|
409
409
|
}
|
|
410
410
|
if (decision === "ask") {
|
|
411
411
|
const reason = permissionAskReason(hookResult.decision === "ask" ? hookResult.messages : undefined, permHook.decision === "ask" ? permHook.messages : undefined);
|
|
412
|
-
const
|
|
412
|
+
const approval = await this.permission.handleAskResult(call.toolName, call.args, reason, {
|
|
413
413
|
sessionId: this.toolCtx?.sessionId,
|
|
414
414
|
});
|
|
415
|
-
if (!approved) {
|
|
415
|
+
if (!approval.approved) {
|
|
416
416
|
return {
|
|
417
417
|
id: call.id,
|
|
418
418
|
toolName: call.toolName,
|
|
419
|
-
error:
|
|
419
|
+
error: approval.failure && approval.failure !== "denied"
|
|
420
|
+
? `Permission approval ${approval.failure} for tool: ${call.toolName}${approval.reason ? `. ${approval.reason}` : ""}`
|
|
421
|
+
: `Permission denied by user for tool: ${call.toolName}${approval.reason ? `. ${approval.reason}` : ""}`,
|
|
420
422
|
isError: true,
|
|
421
423
|
};
|
|
422
424
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Tool as McpTool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export declare function adaptMcpToolSchema(implementation: string | undefined, tool: McpTool): McpTool["inputSchema"];
|
|
3
|
+
export declare function normalizeMcpToolArgs(implementation: string | undefined, tool: McpTool | undefined, args: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Compatibility for Chrome DevTools' optional output/context selectors.
|
|
2
|
+
* A blank selector is not an output filename or an intentional isolated context.
|
|
3
|
+
* Match the server implementation AND its declared tool shape; an unrelated
|
|
4
|
+
* tool's empty text, input path, or required parameter must remain untouched. */
|
|
5
|
+
function optionalChromeSelectors(implementation, tool) {
|
|
6
|
+
if (implementation !== "chrome_devtools")
|
|
7
|
+
return [];
|
|
8
|
+
const properties = tool.inputSchema.properties;
|
|
9
|
+
const required = new Set(tool.inputSchema.required ?? []);
|
|
10
|
+
if (!properties)
|
|
11
|
+
return [];
|
|
12
|
+
const expected = {
|
|
13
|
+
take_snapshot: { selectors: ["filePath"], signature: { verbose: "boolean" } },
|
|
14
|
+
take_screenshot: { selectors: ["filePath"], signature: { format: "string" } },
|
|
15
|
+
evaluate_script: { selectors: ["filePath"], signature: { function: "string" } },
|
|
16
|
+
get_network_request: {
|
|
17
|
+
selectors: ["requestFilePath", "responseFilePath"],
|
|
18
|
+
signature: { reqid: "number" },
|
|
19
|
+
},
|
|
20
|
+
new_page: { selectors: ["isolatedContext"], signature: { url: "string" } },
|
|
21
|
+
};
|
|
22
|
+
const contract = expected[tool.name];
|
|
23
|
+
if (!contract ||
|
|
24
|
+
Object.entries(contract.signature).some(([key, type]) => properties[key]?.type !== type))
|
|
25
|
+
return [];
|
|
26
|
+
return contract.selectors.filter((key) => properties[key]?.type === "string" && !required.has(key));
|
|
27
|
+
}
|
|
28
|
+
export function adaptMcpToolSchema(implementation, tool) {
|
|
29
|
+
const selectors = optionalChromeSelectors(implementation, tool);
|
|
30
|
+
if (!selectors.length)
|
|
31
|
+
return tool.inputSchema;
|
|
32
|
+
const properties = { ...tool.inputSchema.properties };
|
|
33
|
+
for (const key of selectors) {
|
|
34
|
+
const property = properties[key];
|
|
35
|
+
properties[key] = {
|
|
36
|
+
...property,
|
|
37
|
+
minLength: Math.max(typeof property.minLength === "number" ? property.minLength : 0, 1),
|
|
38
|
+
description: `${property.description ?? ""} Omit this optional field when unused; do not send an empty string.`,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return { ...tool.inputSchema, properties };
|
|
42
|
+
}
|
|
43
|
+
export function normalizeMcpToolArgs(implementation, tool, args) {
|
|
44
|
+
const normalized = { ...args };
|
|
45
|
+
if (tool)
|
|
46
|
+
for (const key of optionalChromeSelectors(implementation, tool)) {
|
|
47
|
+
if (normalized[key] === "")
|
|
48
|
+
delete normalized[key];
|
|
49
|
+
}
|
|
50
|
+
return normalized;
|
|
51
|
+
}
|
|
@@ -8,6 +8,8 @@ import type { MCPServerConfig, RegisteredTool } from "../types.js";
|
|
|
8
8
|
import type { CredentialType } from "../credentials/types.js";
|
|
9
9
|
import { ToolRegistry } from "./registry.js";
|
|
10
10
|
import { type CredentialAccess } from "../credentials/access.js";
|
|
11
|
+
import { type McpWorkspaceScope } from "./mcp-workspace.js";
|
|
12
|
+
export type { McpWorkspaceScope } from "./mcp-workspace.js";
|
|
11
13
|
interface MCPResourceInfo {
|
|
12
14
|
uri: string;
|
|
13
15
|
name: string;
|
|
@@ -78,7 +80,7 @@ export declare function spillMcpImage(serverName: string, toolName: string, base
|
|
|
78
80
|
}): Promise<string>;
|
|
79
81
|
export declare function wrapMcpOutput(serverName: string, toolName: string, body: string): string;
|
|
80
82
|
export declare function stripInternalToolArgs(args: Record<string, unknown>): Record<string, unknown>;
|
|
81
|
-
export declare function buildRegisteredTool(serverName: string, tool: McpTool): RegisteredTool;
|
|
83
|
+
export declare function buildRegisteredTool(serverName: string, tool: McpTool, implementation?: string): RegisteredTool;
|
|
82
84
|
/**
|
|
83
85
|
* Per-server outcome of a connectAll() sweep (see the optional onServerEvent
|
|
84
86
|
* parameter). The engine forwards these onto the `notification` hook so hosts
|
|
@@ -95,26 +97,21 @@ export declare class MCPManager {
|
|
|
95
97
|
private connections;
|
|
96
98
|
private registeredToolsByServer;
|
|
97
99
|
private desiredServerNames;
|
|
98
|
-
/**
|
|
99
|
-
* In-flight connect()s keyed by server name. When the broadcast config
|
|
100
|
-
* reload (server.ts forEachSession → every session's refreshRuntimeConfig)
|
|
101
|
-
* calls connectAll for the SAME `added` server on this ONE shared pool, K
|
|
102
|
-
* concurrent connect(name) calls would each start a fresh handshake because
|
|
103
|
-
* `connections.has(name)` only becomes true AFTER the handshake completes —
|
|
104
|
-
* a thundering herd of duplicate connections racing to set(). Coalescing by
|
|
105
|
-
* name here collapses them to a SINGLE underlying connection; the late
|
|
106
|
-
* callers await the same promise and return. Cleared in finally so a failed
|
|
107
|
-
* connect can be retried later.
|
|
108
|
-
*/
|
|
100
|
+
/** Concurrent handshakes share only an identical server + cwd + root scope. */
|
|
109
101
|
private connecting;
|
|
110
102
|
/** Per-owner (engine) desired server sets — see reconcile()'s shared-pool note. */
|
|
111
103
|
private desiredByOwner;
|
|
104
|
+
private scopeByOwner;
|
|
105
|
+
private connectionKeysByOwner;
|
|
106
|
+
private connectionGeneration;
|
|
112
107
|
constructor(toolRegistry: ToolRegistry);
|
|
113
108
|
static getInstance(): MCPManager;
|
|
109
|
+
/** Resolve generic MCP builtins through the current run, never another pool. */
|
|
110
|
+
static forContext(workspace?: McpWorkspaceScope): MCPManager;
|
|
114
111
|
/**
|
|
115
112
|
* Connect to all configured MCP servers and register their tools.
|
|
116
113
|
*/
|
|
117
|
-
connectAll(servers: Record<string, MCPServerConfig>, owner?: unknown, onServerEvent?: (event: McpServerLifecycleEvent) => void): Promise<void>;
|
|
114
|
+
connectAll(servers: Record<string, MCPServerConfig>, owner?: unknown, onServerEvent?: (event: McpServerLifecycleEvent) => void, workspace?: McpWorkspaceScope): Promise<void>;
|
|
118
115
|
reconcile(servers: Record<string, MCPServerConfig>, owner?: unknown): Promise<void>;
|
|
119
116
|
/**
|
|
120
117
|
* Remove one owner from the shared desired-server pool and disconnect servers
|
|
@@ -123,48 +120,52 @@ export declare class MCPManager {
|
|
|
123
120
|
* worker shutdown.
|
|
124
121
|
*/
|
|
125
122
|
unregisterOwner(owner: unknown): Promise<void>;
|
|
123
|
+
private pruneUnusedScopedConnections;
|
|
124
|
+
private managedConnectionKeys;
|
|
126
125
|
private enabledServerNames;
|
|
127
126
|
/** Union of every registered owner's desired set; null when none registered. */
|
|
128
127
|
private unionDesired;
|
|
129
128
|
/**
|
|
130
129
|
* Connect to a single MCP server.
|
|
131
130
|
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* awaited rather than restarted (#5 — thundering-herd guard on the shared
|
|
135
|
-
* pool). The actual handshake lives in `performConnect`.
|
|
131
|
+
* Calls for the same server and canonical workspace scope share one pending
|
|
132
|
+
* handshake. Other workspace scopes always get their own transport.
|
|
136
133
|
*/
|
|
137
|
-
connect(name: string, config: MCPServerConfig): Promise<void>;
|
|
134
|
+
connect(name: string, config: MCPServerConfig, workspace?: McpWorkspaceScope): Promise<void>;
|
|
138
135
|
/**
|
|
139
136
|
* Perform the actual handshake + tool discovery for one server. Separated
|
|
140
137
|
* from `connect` so the coalescing/dedup logic stays in one place. Override
|
|
141
138
|
* `connect` (not this) in test doubles that want to count handshakes.
|
|
142
139
|
*/
|
|
143
|
-
protected performConnect(name: string, config: MCPServerConfig): Promise<void>;
|
|
140
|
+
protected performConnect(name: string, config: MCPServerConfig, workspace?: McpWorkspaceScope): Promise<void>;
|
|
144
141
|
/**
|
|
145
142
|
* Discover tools from an MCP server and register them.
|
|
146
143
|
*/
|
|
147
144
|
private discoverTools;
|
|
145
|
+
private scopeForContext;
|
|
146
|
+
private findConnection;
|
|
147
|
+
private connectionForScope;
|
|
148
|
+
/** Refresh an engine's fork after pool discovery; retain all non-MCP tools. */
|
|
149
|
+
syncToolsToRegistry(registry: ToolRegistry, workspace?: McpWorkspaceScope, allowedServers?: ReadonlySet<string>): void;
|
|
150
|
+
private executeRegisteredTool;
|
|
148
151
|
/**
|
|
149
152
|
* Disconnect all MCP servers.
|
|
150
153
|
*/
|
|
151
154
|
disconnectAll(): Promise<void>;
|
|
152
155
|
disconnect(name: string): Promise<void>;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
*/
|
|
156
|
+
private disconnectConnection;
|
|
157
|
+
/** Names remain stable even when several isolated workspace transports exist. */
|
|
156
158
|
listServers(): string[];
|
|
157
159
|
/**
|
|
158
160
|
* Call a tool on a specific MCP server.
|
|
159
161
|
*/
|
|
160
|
-
callTool(serverName: string, toolName: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<unknown>;
|
|
162
|
+
callTool(serverName: string, toolName: string, args: Record<string, unknown>, signal?: AbortSignal, workspace?: McpWorkspaceScope): Promise<unknown>;
|
|
161
163
|
/**
|
|
162
164
|
* List resources from MCP servers.
|
|
163
165
|
*/
|
|
164
|
-
listResources(serverName?: string, signal?: AbortSignal): Promise<MCPResourceInfo[]>;
|
|
166
|
+
listResources(serverName?: string, signal?: AbortSignal, workspace?: McpWorkspaceScope): Promise<MCPResourceInfo[]>;
|
|
165
167
|
/**
|
|
166
168
|
* Read a resource from an MCP server.
|
|
167
169
|
*/
|
|
168
|
-
readResource(serverName: string, uri: string, signal?: AbortSignal): Promise<string>;
|
|
170
|
+
readResource(serverName: string, uri: string, signal?: AbortSignal, workspace?: McpWorkspaceScope): Promise<string>;
|
|
169
171
|
}
|
|
170
|
-
export {};
|