@code-yeongyu/senpi 2026.10.25-2 → 2026.10.25-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/CHANGELOG.md +20 -0
- package/dist/bundle/chunks/{args-JXULI4EH.js → args-B444OQBK.js} +1 -1
- package/dist/bundle/chunks/{auth-4NUNUSTF.js → auth-C77UQA55.js} +1 -1
- package/dist/bundle/chunks/chunk-6O4SEW2W.js +5 -0
- package/dist/bundle/chunks/{chunk-Y5OTHMXO.js → chunk-7CNOCJCN.js} +1 -1
- package/dist/bundle/chunks/{chunk-JRXKLIEQ.js → chunk-7W7OJDIY.js} +4 -4
- package/dist/bundle/chunks/chunk-AX72VNRS.js +27 -0
- package/dist/bundle/chunks/{chunk-LYGAV6KU.js → chunk-C5UFJ7B3.js} +1 -1
- package/dist/bundle/chunks/{chunk-G2UETS2R.js → chunk-CNL6QSUB.js} +4 -4
- package/dist/bundle/chunks/{chunk-2EFVQWXZ.js → chunk-FFQOEC76.js} +3 -3
- package/dist/bundle/chunks/chunk-H3HNMY2W.js +13 -0
- package/dist/bundle/chunks/{chunk-W2BKZBYJ.js → chunk-HVJI5T75.js} +1 -1
- package/dist/bundle/chunks/{chunk-YN7ELQ43.js → chunk-JA2R2ZSE.js} +1 -1
- package/dist/bundle/chunks/chunk-JPGT64RV.js +2 -0
- package/dist/bundle/chunks/chunk-KXB5WIS5.js +4 -0
- package/dist/bundle/chunks/chunk-L73UYAH5.js +3 -0
- package/dist/bundle/chunks/chunk-LTU6UFEX.js +2 -0
- package/dist/bundle/chunks/{chunk-KUE4AQN6.js → chunk-MJ5NNWX4.js} +1 -1
- package/dist/bundle/chunks/{chunk-WFXUCVIR.js → chunk-O3Q2ET6W.js} +2 -5
- package/dist/bundle/chunks/{chunk-MXZPAUFB.js → chunk-ODTGC6YU.js} +1 -1
- package/dist/bundle/chunks/chunk-P3M2PF6K.js +27 -0
- package/dist/bundle/chunks/{chunk-VNN2V74Y.js → chunk-SWJXRC2I.js} +1 -1
- package/dist/bundle/chunks/{chunk-RXKNOEQQ.js → chunk-UQNRW3VU.js} +1 -1
- package/dist/bundle/chunks/{chunk-U67ML6CQ.js → chunk-WD6WBYC5.js} +1 -1
- package/dist/bundle/chunks/chunk-WJOT3DFL.js +2 -0
- package/dist/bundle/chunks/{chunk-XBUSVKWC.js → chunk-WLHNEUGD.js} +1 -1
- package/dist/bundle/chunks/chunk-YI7SPFDN.js +5 -0
- package/dist/bundle/chunks/{chunk-J2U5VDG7.js → chunk-YRF4I43T.js} +28 -28
- package/dist/bundle/chunks/chunk-Z3UYNSVR.js +3 -0
- package/dist/bundle/chunks/cli-main-HEKFFB5S.js +3 -0
- package/dist/bundle/chunks/{client-KWTLTKVV.js → client-WTYEICLH.js} +3 -3
- package/dist/bundle/chunks/dispatch-NYAULNVW.js +9 -0
- package/dist/bundle/chunks/{help-fast-path-ZHZGXAUG.js → help-fast-path-3Z26DQSV.js} +1 -1
- package/dist/bundle/chunks/host-command-Z3WPHJOW.js +2 -0
- package/dist/bundle/chunks/host-lifecycle-ONQIMWMX.js +3 -0
- package/dist/bundle/chunks/host-lifecycle.js +7 -5
- package/dist/bundle/chunks/host-session-command-J65ENSV5.js +20 -0
- package/dist/bundle/chunks/{host-socket-request-AS2OCRLP.js → host-socket-request-3CWE4265.js} +1 -1
- package/dist/bundle/chunks/interactive-mode-DEPQC6TX.js +2 -0
- package/dist/bundle/chunks/mcp-presenter-bootstrap-XUSCQVRC.js +2 -0
- package/dist/bundle/chunks/{multi-session-host-VTTY5MFT.js → multi-session-host-YI2WZOET.js} +12 -9
- package/dist/bundle/chunks/{package-manager-cli-DZFOC3MF.js → package-manager-cli-GHZPJMRF.js} +1 -1
- package/dist/bundle/chunks/{rotation-stream-U7YQMC7H.js → rotation-stream-ZPVCFOVD.js} +1 -1
- package/dist/bundle/chunks/rpc-mode-ORHBGBBV.js +2 -0
- package/dist/bundle/chunks/{rpc-monitor-source-B5NQ4ZVH.js → rpc-monitor-source-FFEQS744.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-SLISTG4V.js → schedule-command-YWG6D6ZF.js} +1 -1
- package/dist/bundle/chunks/session-control-endpoint-36HAQSQO.js +3 -0
- package/dist/bundle/chunks/{session-picker-465FVXQG.js → session-picker-25H5KNYP.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +278 -264
- package/dist/bundle/chunks/{stdio-IEC635SY.js → stdio-YXDKKKQZ.js} +1 -1
- package/dist/bundle/chunks/{streamableHttp-KJI5KE4K.js → streamableHttp-DKIBUWVY.js} +1 -1
- package/dist/bundle/chunks/{types-LLNV23LW.js → types-BJUEQ4II.js} +1 -1
- package/dist/bundle/chunks/zod-compat-RJDXCU7S.js +2 -0
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/host-supervisor.js +7 -5
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/bundle/runtime-manifest.json +1 -1
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.js +9 -0
- package/dist/cli/host-command-args.d.ts +1 -0
- package/dist/cli/host-command-args.js +7 -1
- package/dist/cli/host-command.js +3 -1
- package/dist/core/agent-session.js +22 -7
- package/dist/core/extensions/builtin/goal/index.js +1 -0
- package/dist/core/extensions/builtin/goal/lifecycle-facts.d.ts +3 -0
- package/dist/core/extensions/builtin/mcp/catalog.d.ts +3 -1
- package/dist/core/extensions/builtin/mcp/catalog.js +2 -0
- package/dist/core/extensions/builtin/mcp/connection.d.ts +1 -0
- package/dist/core/extensions/builtin/mcp/connection.js +46 -1
- package/dist/core/extensions/builtin/mcp/elicitation.d.ts +6 -1
- package/dist/core/extensions/builtin/mcp/elicitation.js +56 -2
- package/dist/core/extensions/builtin/mcp/expose/call.js +6 -2
- package/dist/core/extensions/builtin/mcp/expose/session.d.ts +4 -1
- package/dist/core/extensions/builtin/mcp/expose/session.js +7 -0
- package/dist/core/extensions/builtin/mcp/health.js +5 -0
- package/dist/core/extensions/builtin/mcp/host-registry.js +7 -1
- package/dist/core/extensions/builtin/mcp/index.js +2 -0
- package/dist/core/extensions/builtin/mcp/modern/client.d.ts +5 -0
- package/dist/core/extensions/builtin/mcp/modern/client.js +15 -0
- package/dist/core/extensions/builtin/mcp/modern/consent-queue.d.ts +2 -0
- package/dist/core/extensions/builtin/mcp/modern/consent-queue.js +59 -0
- package/dist/core/extensions/builtin/mcp/modern/diagnostics.d.ts +4 -0
- package/dist/core/extensions/builtin/mcp/modern/diagnostics.js +39 -0
- package/dist/core/extensions/builtin/mcp/modern/dispatch.js +21 -11
- package/dist/core/extensions/builtin/mcp/modern/elicitation.d.ts +14 -0
- package/dist/core/extensions/builtin/mcp/modern/elicitation.js +145 -0
- package/dist/core/extensions/builtin/mcp/modern/errors.d.ts +21 -0
- package/dist/core/extensions/builtin/mcp/modern/errors.js +23 -0
- package/dist/core/extensions/builtin/mcp/modern/form-schema.d.ts +20 -0
- package/dist/core/extensions/builtin/mcp/modern/form-schema.js +153 -0
- package/dist/core/extensions/builtin/mcp/modern/http-fetch.d.ts +3 -1
- package/dist/core/extensions/builtin/mcp/modern/http-fetch.js +8 -2
- package/dist/core/extensions/builtin/mcp/modern/inputs.d.ts +11 -0
- package/dist/core/extensions/builtin/mcp/modern/inputs.js +65 -0
- package/dist/core/extensions/builtin/mcp/modern/parameter-headers.d.ts +11 -0
- package/dist/core/extensions/builtin/mcp/modern/parameter-headers.js +109 -0
- package/dist/core/extensions/builtin/mcp/modern/request.d.ts +20 -0
- package/dist/core/extensions/builtin/mcp/modern/request.js +292 -0
- package/dist/core/extensions/builtin/mcp/modern/stdio-probe.d.ts +1 -1
- package/dist/core/extensions/builtin/mcp/modern/stdio-probe.js +54 -6
- package/dist/core/extensions/builtin/mcp/modern/transport.js +80 -14
- package/dist/core/extensions/builtin/mcp/modern/wire.js +11 -7
- package/dist/core/extensions/builtin/mcp/prompts.d.ts +5 -1
- package/dist/core/extensions/builtin/mcp/prompts.js +6 -1
- package/dist/core/extensions/builtin/mcp/request-origin.d.ts +47 -0
- package/dist/core/extensions/builtin/mcp/request-origin.js +59 -0
- package/dist/core/extensions/builtin/mcp/resources.d.ts +4 -1
- package/dist/core/extensions/builtin/mcp/resources.js +19 -4
- package/dist/core/extensions/builtin/mcp/sdk.lazy.d.ts +3 -1
- package/dist/core/extensions/builtin/mcp/sdk.lazy.js +3 -1
- package/dist/core/extensions/builtin/mcp/service-register.d.ts +4 -1
- package/dist/core/extensions/builtin/mcp/service-register.js +3 -0
- package/dist/core/extensions/builtin/mcp/service-types.d.ts +2 -1
- package/dist/core/extensions/builtin/mcp/service.d.ts +1 -0
- package/dist/core/extensions/builtin/mcp/service.js +79 -4
- package/dist/core/extensions/builtin/mcp/shared-connection.js +36 -2
- package/dist/core/extensions/builtin/mcp/shared-lease.d.ts +1 -0
- package/dist/core/extensions/builtin/mcp/shared-lease.js +9 -0
- package/dist/core/extensions/builtin/mcp/transport-sdk.d.ts +3 -2
- package/dist/core/extensions/builtin/mcp/transport-sdk.js +56 -25
- package/dist/core/extensions/builtin/mcp/wrap.d.ts +7 -0
- package/dist/core/extensions/builtin/mcp/wrap.js +6 -0
- package/dist/core/extensions/runner.js +3 -2
- package/dist/core/extensions/types.d.ts +2 -0
- package/dist/core/lifecycle-ledger.d.ts +1 -0
- package/dist/core/lifecycle-ledger.js +7 -2
- package/dist/core/lifecycle-record.js +3 -0
- package/dist/core/lifecycle-session-binding.d.ts +11 -1
- package/dist/core/lifecycle-session-binding.js +29 -2
- package/dist/core/lifecycle-stop.d.ts +41 -0
- package/dist/core/lifecycle-stop.js +92 -0
- package/dist/core/mcp-form-types.d.ts +89 -0
- package/dist/core/mcp-form-types.js +23 -0
- package/dist/core/mcp-mrtr-presentations.d.ts +15 -0
- package/dist/core/mcp-mrtr-presentations.js +17 -0
- package/dist/core/session-lifecycle-types.d.ts +15 -0
- package/dist/core/session-lifecycle.d.ts +17 -1
- package/dist/core/session-lifecycle.js +40 -2
- package/dist/main.js +5 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +1 -0
- package/dist/modes/interactive/components/extension-selector.js +4 -0
- package/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/dist/modes/interactive/interactive-mode.js +34 -8
- package/dist/modes/interactive/mcp-local-presenter.d.ts +5 -0
- package/dist/modes/interactive/mcp-local-presenter.js +109 -0
- package/dist/modes/rpc/connection-handler.d.ts +1 -0
- package/dist/modes/rpc/connection-handler.js +7 -1
- package/dist/modes/rpc/host-capabilities.d.ts +1 -0
- package/dist/modes/rpc/host-capabilities.js +2 -1
- package/dist/modes/rpc/host-ensure-start.js +13 -2
- package/dist/modes/rpc/host-ensure-types.d.ts +2 -0
- package/dist/modes/rpc/host-ensure.js +1 -0
- package/dist/modes/rpc/host-handoff.d.ts +2 -0
- package/dist/modes/rpc/host-handover-wire.d.ts +2 -0
- package/dist/modes/rpc/host-handover-wire.js +1 -0
- package/dist/modes/rpc/host-lifecycle-launch.d.ts +1 -0
- package/dist/modes/rpc/host-lifecycle-launch.js +43 -2
- package/dist/modes/rpc/host-runner.d.ts +2 -0
- package/dist/modes/rpc/host-runner.js +8 -6
- package/dist/modes/rpc/host-successor.js +11 -1
- package/dist/modes/rpc/mcp-form-dialog.d.ts +45 -0
- package/dist/modes/rpc/mcp-form-dialog.js +159 -0
- package/dist/modes/rpc/mcp-form-worker.d.ts +14 -0
- package/dist/modes/rpc/mcp-form-worker.js +167 -0
- package/dist/modes/rpc/mcp-presenter-authority.d.ts +53 -0
- package/dist/modes/rpc/mcp-presenter-authority.js +309 -0
- package/dist/modes/rpc/mcp-presenter-bootstrap.d.ts +8 -0
- package/dist/modes/rpc/mcp-presenter-bootstrap.js +111 -0
- package/dist/modes/rpc/mcp-presenter-control.d.ts +24 -0
- package/dist/modes/rpc/mcp-presenter-control.js +330 -0
- package/dist/modes/rpc/multi-session-host.d.ts +3 -0
- package/dist/modes/rpc/multi-session-host.js +36 -1
- package/dist/modes/rpc/session-binding.js +6 -1
- package/dist/modes/rpc/session-event-writer.d.ts +14 -0
- package/dist/modes/rpc/session-event-writer.js +128 -1
- package/dist/modes/rpc/session-router-routing.js +1 -0
- package/dist/modes/rpc/session-worker-client.d.ts +3 -0
- package/dist/modes/rpc/session-worker-client.js +89 -0
- package/dist/modes/rpc/session-worker-protocol.d.ts +41 -0
- package/dist/modes/rpc/session-worker.js +9 -0
- package/docs/extensions.md +5 -0
- package/docs/mcp.md +20 -3
- package/docs/rpc.md +111 -0
- package/package.json +6 -6
- package/dist/bundle/chunks/chunk-B6TPQDBW.js +0 -5
- package/dist/bundle/chunks/chunk-CDRFFHLL.js +0 -4
- package/dist/bundle/chunks/chunk-HPCS4HM4.js +0 -27
- package/dist/bundle/chunks/chunk-KJZAY5YH.js +0 -27
- package/dist/bundle/chunks/chunk-OI4NMCKP.js +0 -3
- package/dist/bundle/chunks/chunk-SCVRKIFK.js +0 -2
- package/dist/bundle/chunks/cli-main-SWKFMTZQ.js +0 -3
- package/dist/bundle/chunks/dispatch-DEP4PEDZ.js +0 -10
- package/dist/bundle/chunks/host-command-BC6UWP33.js +0 -2
- package/dist/bundle/chunks/host-lifecycle-TN5NEGNF.js +0 -3
- package/dist/bundle/chunks/host-session-command-MGVBLBRV.js +0 -20
- package/dist/bundle/chunks/interactive-mode-SCSROHD5.js +0 -2
- package/dist/bundle/chunks/rpc-mode-TOXYD4XA.js +0 -2
- package/dist/bundle/chunks/session-control-endpoint-HFFMBALG.js +0 -3
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { JSONRPCMessageSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import { deriveModernHeaders, MODERN_PROTOCOL_VERSION, modernizeRequest } from "./wire.js";
|
|
3
|
+
import { AuthError } from "../errors.js";
|
|
4
|
+
import { sanitizeModernMessage } from "./diagnostics.js";
|
|
5
|
+
import { McpMrtrError } from "./errors.js";
|
|
6
|
+
import { getModernDispatchGuard, modernDispatchGuard } from "./request.js";
|
|
7
|
+
import { clearMcpParameterHeaders, ModernParameterHeaders } from "./parameter-headers.js";
|
|
3
8
|
export class ModernTransportError extends Error {
|
|
4
9
|
constructor(message) {
|
|
5
10
|
super(message);
|
|
@@ -10,6 +15,9 @@ export class ModernTransportError extends Error {
|
|
|
10
15
|
export class ModernHttpTransport {
|
|
11
16
|
#options;
|
|
12
17
|
#abort = new AbortController();
|
|
18
|
+
#attempts = new Map();
|
|
19
|
+
#toolLists = new Map();
|
|
20
|
+
#parameterHeaders = new ModernParameterHeaders();
|
|
13
21
|
#started = false;
|
|
14
22
|
#closed = false;
|
|
15
23
|
constructor(options) {
|
|
@@ -30,9 +38,24 @@ export class ModernHttpTransport {
|
|
|
30
38
|
async send(message) {
|
|
31
39
|
if (!this.#started || this.#closed)
|
|
32
40
|
throw new ModernTransportError("Modern MCP transport is not open");
|
|
41
|
+
if ("method" in message && message.method === "notifications/cancelled") {
|
|
42
|
+
const id = message.params?.requestId;
|
|
43
|
+
if (typeof id === "string" || typeof id === "number")
|
|
44
|
+
this.#attempts.get(id)?.abort();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const id = "method" in message && "id" in message ? message.id : undefined;
|
|
48
|
+
if (id !== undefined && "method" in message && message.method === "tools/list") {
|
|
49
|
+
this.#toolLists.set(id, message.params?.cursor === undefined);
|
|
50
|
+
}
|
|
51
|
+
const controller = new AbortController();
|
|
52
|
+
if (id !== undefined)
|
|
53
|
+
this.#attempts.set(id, controller);
|
|
54
|
+
const signal = AbortSignal.any([this.#abort.signal, controller.signal]);
|
|
33
55
|
try {
|
|
34
56
|
const version = this.#options.protocolVersion ?? MODERN_PROTOCOL_VERSION;
|
|
35
57
|
const headers = new Headers(this.#options.headers);
|
|
58
|
+
clearMcpParameterHeaders(headers);
|
|
36
59
|
// Auth headers pass through, but protocol routing is exclusively derived from the body.
|
|
37
60
|
for (const name of ["Mcp-Session-Id", "Mcp-Name", "Mcp-Method", "MCP-Protocol-Version"])
|
|
38
61
|
headers.delete(name);
|
|
@@ -43,6 +66,9 @@ export class ModernHttpTransport {
|
|
|
43
66
|
const request = modernizeRequest("id" in message ? message.id : 0, message.method, this.#options.clientInfo, this.#options.clientCapabilities, version, message.params);
|
|
44
67
|
for (const [name, value] of Object.entries(deriveModernHeaders(request)))
|
|
45
68
|
headers.set(name, value);
|
|
69
|
+
if (request.method === "tools/call") {
|
|
70
|
+
this.#parameterHeaders.append(headers, request.params.name, request.params.arguments);
|
|
71
|
+
}
|
|
46
72
|
if ("id" in message) {
|
|
47
73
|
body = request;
|
|
48
74
|
}
|
|
@@ -55,13 +81,24 @@ export class ModernHttpTransport {
|
|
|
55
81
|
// JSON-RPC replies have no method or params; do not turn them into requests.
|
|
56
82
|
headers.set("MCP-Protocol-Version", version);
|
|
57
83
|
}
|
|
58
|
-
const
|
|
84
|
+
const guard = "method" in message ? getModernDispatchGuard(message.params) : undefined;
|
|
85
|
+
guard?.();
|
|
86
|
+
const init = {
|
|
59
87
|
method: "POST",
|
|
60
88
|
headers,
|
|
61
89
|
body: JSON.stringify(body),
|
|
62
|
-
signal
|
|
63
|
-
|
|
64
|
-
|
|
90
|
+
signal,
|
|
91
|
+
[modernDispatchGuard]: guard,
|
|
92
|
+
};
|
|
93
|
+
const response = await this.#options.fetch(this.#options.url, init);
|
|
94
|
+
signal.throwIfAborted();
|
|
95
|
+
if (response.status === 401 || response.status === 403) {
|
|
96
|
+
await response.body?.cancel();
|
|
97
|
+
throw new AuthError("MCP server needs authentication; use /mcp auth-start.", {
|
|
98
|
+
phase: "auth",
|
|
99
|
+
retriable: false,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
65
102
|
if (response.status === 202 || response.status === 204)
|
|
66
103
|
return;
|
|
67
104
|
const mediaType = response.headers.get("Content-Type")?.split(";")[0].trim().toLowerCase();
|
|
@@ -71,35 +108,64 @@ export class ModernHttpTransport {
|
|
|
71
108
|
if (!response.ok && !("error" in incoming)) {
|
|
72
109
|
throw new ModernTransportError(`Modern MCP POST failed with HTTP ${response.status}`);
|
|
73
110
|
}
|
|
74
|
-
|
|
75
|
-
this
|
|
111
|
+
signal.throwIfAborted();
|
|
112
|
+
this.#deliver(incoming, id);
|
|
76
113
|
}
|
|
77
114
|
else if (response.ok && mediaType === "text/event-stream" && response.body) {
|
|
78
|
-
await this.#consumeSse(response.body,
|
|
115
|
+
await this.#consumeSse(response.body, id, signal);
|
|
79
116
|
}
|
|
80
117
|
else {
|
|
81
118
|
throw new ModernTransportError(`Modern MCP POST failed with HTTP ${response.status} (${mediaType ?? "no content type"})`);
|
|
82
119
|
}
|
|
83
120
|
}
|
|
84
121
|
catch (error) {
|
|
85
|
-
const failure = error instanceof
|
|
122
|
+
const failure = error instanceof McpMrtrError || error instanceof AuthError
|
|
123
|
+
? error
|
|
124
|
+
: new McpMrtrError("MCP_MRTR_TRANSPORT_FAILED");
|
|
86
125
|
this.onerror?.(failure);
|
|
87
126
|
throw failure;
|
|
88
127
|
}
|
|
128
|
+
finally {
|
|
129
|
+
if (id !== undefined)
|
|
130
|
+
this.#attempts.delete(id);
|
|
131
|
+
if (id !== undefined)
|
|
132
|
+
this.#toolLists.delete(id);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
#deliver(incoming, expected) {
|
|
136
|
+
if ("id" in incoming && (expected === undefined || incoming.id !== expected))
|
|
137
|
+
throw new McpMrtrError("MCP_MRTR_INVALID_RESULT");
|
|
138
|
+
if ("id" in incoming && "result" in incoming && this.#toolLists.has(incoming.id)) {
|
|
139
|
+
const result = incoming.result;
|
|
140
|
+
if (Array.isArray(result.tools)) {
|
|
141
|
+
incoming = {
|
|
142
|
+
...incoming,
|
|
143
|
+
result: {
|
|
144
|
+
...result,
|
|
145
|
+
tools: this.#parameterHeaders.filterTools(result.tools, this.#toolLists.get(incoming.id) === true),
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const safe = sanitizeModernMessage(incoming);
|
|
151
|
+
if (safe)
|
|
152
|
+
this.onmessage?.(safe);
|
|
89
153
|
}
|
|
90
|
-
async #consumeSse(stream, requestId) {
|
|
154
|
+
async #consumeSse(stream, requestId, signal) {
|
|
91
155
|
const reader = stream.getReader();
|
|
92
156
|
const decoder = new TextDecoder();
|
|
93
157
|
const aborted = Promise.withResolvers();
|
|
94
|
-
const onabort = () => aborted.reject(
|
|
95
|
-
|
|
158
|
+
const onabort = () => aborted.reject(signal.reason);
|
|
159
|
+
signal.addEventListener("abort", onabort, { once: true });
|
|
160
|
+
if (signal.aborted)
|
|
161
|
+
onabort();
|
|
96
162
|
let buffer = "";
|
|
97
163
|
let data = [];
|
|
98
164
|
let event = "";
|
|
99
165
|
try {
|
|
100
166
|
while (true) {
|
|
101
167
|
const { value, done } = await Promise.race([reader.read(), aborted.promise]);
|
|
102
|
-
|
|
168
|
+
signal.throwIfAborted();
|
|
103
169
|
buffer += done ? decoder.decode() : decoder.decode(value, { stream: true });
|
|
104
170
|
while (true) {
|
|
105
171
|
const match = /[\r\n]/.exec(buffer);
|
|
@@ -114,7 +180,7 @@ export class ModernHttpTransport {
|
|
|
114
180
|
if (line === "") {
|
|
115
181
|
if (data.length > 0 && (event === "" || event === "message")) {
|
|
116
182
|
const incoming = JSONRPCMessageSchema.parse(JSON.parse(data.join("\n")));
|
|
117
|
-
this
|
|
183
|
+
this.#deliver(incoming, requestId);
|
|
118
184
|
if ("id" in incoming && !("method" in incoming) && incoming.id === requestId)
|
|
119
185
|
return;
|
|
120
186
|
}
|
|
@@ -139,7 +205,7 @@ export class ModernHttpTransport {
|
|
|
139
205
|
}
|
|
140
206
|
}
|
|
141
207
|
finally {
|
|
142
|
-
|
|
208
|
+
signal.removeEventListener("abort", onabort);
|
|
143
209
|
await reader.cancel();
|
|
144
210
|
reader.releaseLock();
|
|
145
211
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { encodeMcpHeaderValue } from "./parameter-headers.js";
|
|
2
2
|
export const MODERN_PROTOCOL_VERSION = "2026-07-28";
|
|
3
3
|
export const MODERN_ERROR_CODES = {
|
|
4
4
|
HeaderMismatch: -32020,
|
|
@@ -24,9 +24,17 @@ export function buildModernRequest(id, method, clientInfo, clientCapabilities, p
|
|
|
24
24
|
/** Rewrite an outgoing SDK request or notification into the modern wire shape at the negotiated version. */
|
|
25
25
|
export function modernizeRequest(id, method, clientInfo, clientCapabilities, version, params) {
|
|
26
26
|
const built = buildModernRequest(id, method, clientInfo, clientCapabilities, params);
|
|
27
|
+
const capabilities = params?._meta?.["io.modelcontextprotocol/clientCapabilities"];
|
|
27
28
|
return {
|
|
28
29
|
...built,
|
|
29
|
-
params: {
|
|
30
|
+
params: {
|
|
31
|
+
...built.params,
|
|
32
|
+
_meta: {
|
|
33
|
+
...built.params._meta,
|
|
34
|
+
"io.modelcontextprotocol/clientCapabilities": isRecord(capabilities) ? capabilities : clientCapabilities,
|
|
35
|
+
"io.modelcontextprotocol/protocolVersion": version,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
30
38
|
};
|
|
31
39
|
}
|
|
32
40
|
/** Derive protocol headers from the same request that will be serialized. */
|
|
@@ -41,11 +49,7 @@ export function deriveModernHeaders(request) {
|
|
|
41
49
|
? request.params.name
|
|
42
50
|
: undefined;
|
|
43
51
|
if (typeof name === "string") {
|
|
44
|
-
|
|
45
|
-
headers["Mcp-Name"] =
|
|
46
|
-
/^[\x20-\x7E]*$/.test(name) && !name.startsWith("base64:")
|
|
47
|
-
? name
|
|
48
|
-
: `base64:${Buffer.from(name, "utf8").toString("base64url")}`;
|
|
52
|
+
headers["Mcp-Name"] = encodeMcpHeaderValue(name);
|
|
49
53
|
}
|
|
50
54
|
return headers;
|
|
51
55
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "../../types.ts";
|
|
1
|
+
import type { ExtensionAPI, ExtensionUIContext } from "../../types.ts";
|
|
2
2
|
import type { McpCachedServerCatalog } from "./catalog-cache.ts";
|
|
3
3
|
import type { ServerConnection } from "./connection.ts";
|
|
4
4
|
import type { McpService } from "./service.ts";
|
|
5
|
+
import { type McpRequestOrigin } from "./request-origin.ts";
|
|
5
6
|
export interface McpPromptServer {
|
|
7
|
+
readonly ensureFresh?: () => Promise<void>;
|
|
8
|
+
readonly requestOrigin?: () => McpRequestOrigin | undefined;
|
|
9
|
+
readonly bindPresentation?: (ui: ExtensionUIContext) => void;
|
|
6
10
|
readonly server: string;
|
|
7
11
|
readonly connection: ServerConnection;
|
|
8
12
|
readonly requestTimeoutMs?: number;
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
// last-wins, and prompts removed server-side keep a stale command until the
|
|
11
11
|
// next session — invoking one surfaces the server error as a notice.
|
|
12
12
|
import { createMcpLogger } from "./log.js";
|
|
13
|
+
import { mcpRequestOptions } from "./request-origin.js";
|
|
14
|
+
import { ensureMcpToolCallConnection } from "./health.js";
|
|
13
15
|
const registeredCommandNames = new Set();
|
|
14
16
|
/** Test seam: forget which commands were registered (module-level last-wins). */
|
|
15
17
|
export function resetMcpPromptCommandsForTests() {
|
|
@@ -34,10 +36,13 @@ export function registerMcpPromptCommands(serviceOrPi, piOrServers, serversArg)
|
|
|
34
36
|
description: prompt.description ?? `MCP prompt ${prompt.name} from ${server.server}`,
|
|
35
37
|
handler: async (_args, ctx) => {
|
|
36
38
|
try {
|
|
39
|
+
server.bindPresentation?.(ctx.ui);
|
|
37
40
|
const collected = await collectPromptArguments(prompt.arguments ?? [], ctx);
|
|
38
41
|
if (collected === undefined)
|
|
39
42
|
return;
|
|
40
|
-
|
|
43
|
+
if (server.requestOrigin)
|
|
44
|
+
await ensureMcpToolCallConnection(server.connection, server.ensureFresh);
|
|
45
|
+
const result = await server.connection.client.getPrompt({ arguments: collected, name: prompt.name }, mcpRequestOptions(server.requestOrigin?.(), { timeout: server.requestTimeoutMs }));
|
|
41
46
|
ctx.ui.setEditorText(flattenPromptMessages(result.messages));
|
|
42
47
|
}
|
|
43
48
|
catch (error) {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import type { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
3
|
+
import type { McpMrtrPresentation } from "../../../mcp-mrtr-presentations.ts";
|
|
4
|
+
import type { McpFormPresentation } from "../../../mcp-form-types.ts";
|
|
5
|
+
import type { ServerConnection } from "./connection.ts";
|
|
6
|
+
declare const originOption: unique symbol;
|
|
7
|
+
export declare const physicalMcpClient: (client: Client) => Client;
|
|
8
|
+
export declare function registerMcpClientAlias(alias: Client, physical: Client): void;
|
|
9
|
+
export interface McpRequestOrigin {
|
|
10
|
+
readonly binding: object;
|
|
11
|
+
readonly connection: ServerConnection;
|
|
12
|
+
readonly signal: AbortSignal;
|
|
13
|
+
readonly presentation?: McpMrtrPresentation;
|
|
14
|
+
readonly privateForm?: McpFormPresentation;
|
|
15
|
+
readonly privateFormsEnforced?: boolean;
|
|
16
|
+
readonly serverLabel: string;
|
|
17
|
+
readonly serverSource?: "user" | "project" | "plugin";
|
|
18
|
+
readonly isCurrent: () => boolean;
|
|
19
|
+
readonly resolveAuthority: (signal: AbortSignal) => Promise<unknown>;
|
|
20
|
+
}
|
|
21
|
+
export declare function beginLegacyMcpOperation(client: Client, origin: McpRequestOrigin, caller?: AbortSignal): () => void;
|
|
22
|
+
export declare function legacyMcpOperation(client: Client): "ambiguous" | {
|
|
23
|
+
readonly origin: McpRequestOrigin;
|
|
24
|
+
readonly signal: AbortSignal;
|
|
25
|
+
} | undefined;
|
|
26
|
+
/** Issued by the binding-specific registration boundary, never from JSON/model arguments. */
|
|
27
|
+
export declare function createMcpRequestOrigin(origin: McpRequestOrigin): McpRequestOrigin;
|
|
28
|
+
export declare function mcpRequestOptions(origin: McpRequestOrigin | undefined, options?: RequestOptions): RequestOptions & {
|
|
29
|
+
[originOption]?: McpRequestOrigin;
|
|
30
|
+
};
|
|
31
|
+
export declare function takeMcpRequestOrigin(options: RequestOptions | undefined, client: Client): {
|
|
32
|
+
origin: McpRequestOrigin | undefined;
|
|
33
|
+
sdkOptions: {
|
|
34
|
+
relatedRequestId?: import("@modelcontextprotocol/sdk/types").RequestId;
|
|
35
|
+
resumptionToken?: string;
|
|
36
|
+
onresumptiontoken?: (token: string) => void;
|
|
37
|
+
onprogress?: import("@modelcontextprotocol/sdk/shared/protocol.js").ProgressCallback;
|
|
38
|
+
signal?: AbortSignal;
|
|
39
|
+
timeout?: number;
|
|
40
|
+
resetTimeoutOnProgress?: boolean;
|
|
41
|
+
maxTotalTimeout?: number;
|
|
42
|
+
task?: import("@modelcontextprotocol/sdk/types").TaskCreationParams;
|
|
43
|
+
relatedTask?: import("@modelcontextprotocol/sdk/types").RelatedTaskMetadata;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=request-origin.d.ts.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { McpMrtrError } from "./modern/errors.js";
|
|
2
|
+
const originOption = Symbol("mcp-request-origin");
|
|
3
|
+
const origins = new WeakSet();
|
|
4
|
+
const aliases = new WeakMap();
|
|
5
|
+
export const physicalMcpClient = (client) => aliases.get(client) ?? client;
|
|
6
|
+
export function registerMcpClientAlias(alias, physical) {
|
|
7
|
+
aliases.set(alias, physical);
|
|
8
|
+
}
|
|
9
|
+
const legacyOperations = new WeakMap();
|
|
10
|
+
export function beginLegacyMcpOperation(client, origin, caller) {
|
|
11
|
+
const lifetime = new AbortController();
|
|
12
|
+
const operation = {
|
|
13
|
+
origin,
|
|
14
|
+
signal: AbortSignal.any([origin.signal, lifetime.signal, ...(caller ? [caller] : [])]),
|
|
15
|
+
};
|
|
16
|
+
let operations = legacyOperations.get(client);
|
|
17
|
+
if (!operations) {
|
|
18
|
+
operations = new Set();
|
|
19
|
+
legacyOperations.set(client, operations);
|
|
20
|
+
}
|
|
21
|
+
operations.add(operation);
|
|
22
|
+
return () => {
|
|
23
|
+
operations.delete(operation);
|
|
24
|
+
lifetime.abort();
|
|
25
|
+
if (operations.size === 0)
|
|
26
|
+
legacyOperations.delete(client);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function legacyMcpOperation(client) {
|
|
30
|
+
const operations = legacyOperations.get(client);
|
|
31
|
+
if (operations && operations.size > 1)
|
|
32
|
+
return "ambiguous";
|
|
33
|
+
if (operations?.size !== 1)
|
|
34
|
+
return undefined;
|
|
35
|
+
const operation = operations.values().next().value;
|
|
36
|
+
return operation && !operation.signal.aborted && operation.origin.isCurrent() ? operation : undefined;
|
|
37
|
+
}
|
|
38
|
+
/** Issued by the binding-specific registration boundary, never from JSON/model arguments. */
|
|
39
|
+
export function createMcpRequestOrigin(origin) {
|
|
40
|
+
origins.add(origin);
|
|
41
|
+
return origin;
|
|
42
|
+
}
|
|
43
|
+
export function mcpRequestOptions(origin, options = {}) {
|
|
44
|
+
return origin === undefined ? options : { ...options, [originOption]: origin };
|
|
45
|
+
}
|
|
46
|
+
export function takeMcpRequestOrigin(options, client) {
|
|
47
|
+
const supplied = options;
|
|
48
|
+
const origin = supplied?.[originOption];
|
|
49
|
+
const { [originOption]: _origin, ...sdkOptions } = supplied ?? {};
|
|
50
|
+
if (origin !== undefined) {
|
|
51
|
+
if (!origins.has(origin) || !origin.isCurrent())
|
|
52
|
+
throw new McpMrtrError("MCP_MRTR_CONTEXT_CHANGED");
|
|
53
|
+
const candidate = origin.connection.client;
|
|
54
|
+
if (physicalMcpClient(candidate) !== client)
|
|
55
|
+
throw new McpMrtrError("MCP_MRTR_CONTEXT_CHANGED");
|
|
56
|
+
}
|
|
57
|
+
return { origin, sdkOptions };
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=request-origin.js.map
|
|
@@ -6,7 +6,10 @@ import type { ServerConnection } from "./connection.ts";
|
|
|
6
6
|
import type { McpToolDetails } from "./expose/register.ts";
|
|
7
7
|
import type { McpOutputArtifacts } from "./guard/output-guard.ts";
|
|
8
8
|
import { applyMcpOutputGuard } from "./guard/output-guard.ts";
|
|
9
|
+
import { type McpRequestOrigin } from "./request-origin.ts";
|
|
9
10
|
export interface McpResourceServer {
|
|
11
|
+
readonly ensureFresh?: () => Promise<void>;
|
|
12
|
+
readonly requestOrigin?: () => McpRequestOrigin | undefined;
|
|
10
13
|
readonly server: string;
|
|
11
14
|
readonly connection: ServerConnection;
|
|
12
15
|
readonly agentDir?: string;
|
|
@@ -22,7 +25,7 @@ export declare function ensureMcpResourceSubscriptions(client: Client, resources
|
|
|
22
25
|
uri: string;
|
|
23
26
|
}>): Promise<void>;
|
|
24
27
|
/** Read one resource and flatten its contents to guarded text. */
|
|
25
|
-
export declare function readMcpResourceAsText(server: McpResourceServer, uri: string): Promise<string>;
|
|
28
|
+
export declare function readMcpResourceAsText(server: McpResourceServer, uri: string, signal?: AbortSignal): Promise<string>;
|
|
26
29
|
declare const ListParams: Type.TObject<{
|
|
27
30
|
server: Type.TOptional<Type.TString>;
|
|
28
31
|
}>;
|
|
@@ -16,6 +16,9 @@ import { redactResolvedReferenceData, redactResolvedReferenceValues } from "../.
|
|
|
16
16
|
import { ToolExecError } from "./errors.js";
|
|
17
17
|
import { applyMcpOutputGuard } from "./guard/output-guard.js";
|
|
18
18
|
import { ResourceUpdatedNotificationSchema, registerMcpNotificationHandler } from "./notification-schemas.js";
|
|
19
|
+
import { mcpRequestOptions } from "./request-origin.js";
|
|
20
|
+
import { McpMrtrError } from "./modern/errors.js";
|
|
21
|
+
import { ensureMcpToolCallConnection } from "./health.js";
|
|
19
22
|
/** Route resource updated notifications into the shared refresh path. */
|
|
20
23
|
export function subscribeMcpResourceUpdated(client, onChange) {
|
|
21
24
|
registerMcpNotificationHandler(client, ResourceUpdatedNotificationSchema, () => {
|
|
@@ -29,13 +32,20 @@ export async function ensureMcpResourceSubscriptions(client, resources) {
|
|
|
29
32
|
await Promise.all(resources.map((resource) => client.subscribeResource({ uri: resource.uri }).catch(() => undefined)));
|
|
30
33
|
}
|
|
31
34
|
/** Read one resource and flatten its contents to guarded text. */
|
|
32
|
-
export async function readMcpResourceAsText(server, uri) {
|
|
35
|
+
export async function readMcpResourceAsText(server, uri, signal) {
|
|
33
36
|
let contents;
|
|
34
37
|
try {
|
|
35
|
-
|
|
38
|
+
if (server.requestOrigin)
|
|
39
|
+
await ensureMcpToolCallConnection(server.connection, server.ensureFresh);
|
|
40
|
+
const result = await server.connection.client.readResource({ uri }, mcpRequestOptions(server.requestOrigin?.(), {
|
|
41
|
+
timeout: server.requestTimeoutMs,
|
|
42
|
+
...(signal === undefined ? {} : { signal }),
|
|
43
|
+
}));
|
|
36
44
|
contents = result.contents;
|
|
37
45
|
}
|
|
38
46
|
catch (error) {
|
|
47
|
+
if (error instanceof McpMrtrError)
|
|
48
|
+
throw error;
|
|
39
49
|
throw new ToolExecError(redactResolvedReferenceValues(`Failed to read MCP resource ${uri}: ${error instanceof Error ? error.message : String(error)}`), {
|
|
40
50
|
phase: "call",
|
|
41
51
|
serverName: server.server,
|
|
@@ -93,7 +103,7 @@ export function createMcpResourceTools(servers) {
|
|
|
93
103
|
description: "Read one MCP resource by server name and URI; returns its (guarded) content.",
|
|
94
104
|
parameters: ReadParams,
|
|
95
105
|
executionMode: "parallel",
|
|
96
|
-
async execute(_id, params) {
|
|
106
|
+
async execute(_id, params, signal) {
|
|
97
107
|
const entry = servers().find((candidate) => candidate.server === params.server);
|
|
98
108
|
if (entry === undefined) {
|
|
99
109
|
throw new ToolExecError(redactResolvedReferenceValues(`Unknown MCP server '${params.server}' for resource ${params.uri}.`), {
|
|
@@ -101,7 +111,7 @@ export function createMcpResourceTools(servers) {
|
|
|
101
111
|
serverName: params.server,
|
|
102
112
|
});
|
|
103
113
|
}
|
|
104
|
-
const text = await readMcpResourceAsText(entry, params.uri);
|
|
114
|
+
const text = await readMcpResourceAsText(entry, params.uri, signal);
|
|
105
115
|
return {
|
|
106
116
|
content: [{ type: "text", text }],
|
|
107
117
|
details: redactResolvedReferenceData({
|
|
@@ -137,6 +147,11 @@ export async function expandMcpResourceMentions(text, servers) {
|
|
|
137
147
|
expanded = expanded.replace(mention, `<mcp-resource server="${serverName}" uri="${uri}">\n${body}\n</mcp-resource>`);
|
|
138
148
|
}
|
|
139
149
|
catch (error) {
|
|
150
|
+
if (error instanceof McpMrtrError &&
|
|
151
|
+
["MCP_MRTR_CANCELLED", "MCP_MRTR_CONTEXT_CHANGED", "MCP_MRTR_TIMEOUT"].includes(error.code)) {
|
|
152
|
+
notices.push("MCP resource request canceled; mention left unchanged.");
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
140
155
|
notices.push(`@mcp mention left as-is: ${error instanceof Error ? error.message : String(error)}`);
|
|
141
156
|
}
|
|
142
157
|
}
|
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
*/
|
|
16
16
|
/** `Client` — the MCP client class, built once per transport connection. */
|
|
17
17
|
export declare const loadMcpSdkClient: () => Promise<typeof import("@modelcontextprotocol/sdk/client/index.js")>;
|
|
18
|
+
/** Compatibility parser for final caller schemas at the modern request boundary. */
|
|
19
|
+
export declare const loadMcpSdkZodCompat: () => Promise<typeof import("@modelcontextprotocol/sdk/server/zod-compat.js")>;
|
|
18
20
|
/** `StdioClientTransport` + `getDefaultEnvironment` — stdio servers and the stdio diagnostic rerun. */
|
|
19
21
|
export declare const loadMcpSdkStdioTransport: () => Promise<typeof import("@modelcontextprotocol/sdk/client/stdio.js")>;
|
|
20
|
-
/**
|
|
22
|
+
/** SDK-owned protocol schemas for elicitation and modern request results. */
|
|
21
23
|
export declare const loadMcpSdkTypes: () => Promise<typeof import("@modelcontextprotocol/sdk/types.js")>;
|
|
22
24
|
/** OAuth 2.1 discovery, authorization, token exchange and refresh. */
|
|
23
25
|
export declare const loadMcpSdkAuth: () => Promise<typeof import("@modelcontextprotocol/sdk/client/auth.js")>;
|
|
@@ -36,9 +36,11 @@ function memoizeLoader(load) {
|
|
|
36
36
|
}
|
|
37
37
|
/** `Client` — the MCP client class, built once per transport connection. */
|
|
38
38
|
export const loadMcpSdkClient = memoizeLoader(() => import("@modelcontextprotocol/sdk/client/index.js"));
|
|
39
|
+
/** Compatibility parser for final caller schemas at the modern request boundary. */
|
|
40
|
+
export const loadMcpSdkZodCompat = memoizeLoader(() => import("@modelcontextprotocol/sdk/server/zod-compat.js"));
|
|
39
41
|
/** `StdioClientTransport` + `getDefaultEnvironment` — stdio servers and the stdio diagnostic rerun. */
|
|
40
42
|
export const loadMcpSdkStdioTransport = memoizeLoader(() => import("@modelcontextprotocol/sdk/client/stdio.js"));
|
|
41
|
-
/**
|
|
43
|
+
/** SDK-owned protocol schemas for elicitation and modern request results. */
|
|
42
44
|
export const loadMcpSdkTypes = memoizeLoader(() => import("@modelcontextprotocol/sdk/types.js"));
|
|
43
45
|
let authModule;
|
|
44
46
|
/** OAuth 2.1 discovery, authorization, token exchange and refresh. */
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "../../types.ts";
|
|
1
|
+
import type { ExtensionAPI, ExtensionUIContext } from "../../types.ts";
|
|
2
2
|
import type { ToolSearchService } from "../tool-search/service.ts";
|
|
3
3
|
import type { ResolvedMcpConfig } from "./config-schema.ts";
|
|
4
4
|
import type { McpSessionRegistration } from "./expose/session.ts";
|
|
5
5
|
import type { McpConnectionEntry } from "./service-types.ts";
|
|
6
|
+
import type { McpRequestOrigin } from "./request-origin.ts";
|
|
6
7
|
type McpToolRegistrar = Pick<ExtensionAPI, "getActiveTools" | "setActiveTools" | "registerTool">;
|
|
7
8
|
export interface McpServiceDirectToolRegistrationOptions {
|
|
9
|
+
readonly requestOrigin?: (entry: McpConnectionEntry) => McpRequestOrigin;
|
|
10
|
+
readonly bindPresentation?: (ui: ExtensionUIContext) => void;
|
|
8
11
|
readonly refreshActiveSetWhenEmpty?: boolean;
|
|
9
12
|
readonly onRegistered?: (entry: McpConnectionEntry, identity: string) => void;
|
|
10
13
|
readonly isCurrent?: (entry: McpConnectionEntry) => boolean;
|
|
@@ -39,6 +39,7 @@ export async function registerMcpServiceDirectTools(pi, config, entries, toolSea
|
|
|
39
39
|
ensureFresh: () => entry.authPlan?.refresh?.ensureFresh().then(() => undefined) ?? Promise.resolve(),
|
|
40
40
|
outputGuard: config.settings.outputGuard,
|
|
41
41
|
invocation,
|
|
42
|
+
requestOrigin: () => options.requestOrigin?.(entry),
|
|
42
43
|
});
|
|
43
44
|
return computeMcpExposurePolicy(current, serverConfig, config.settings).filteredEntries.find((candidate) => candidate.tool === tool);
|
|
44
45
|
},
|
|
@@ -54,6 +55,8 @@ export async function registerMcpServiceDirectTools(pi, config, entries, toolSea
|
|
|
54
55
|
startupCatalogPending,
|
|
55
56
|
localCatalogOnly: true,
|
|
56
57
|
invocation,
|
|
58
|
+
requestOrigin: () => options.requestOrigin?.(entry),
|
|
59
|
+
bindPresentation: options.bindPresentation,
|
|
57
60
|
onRegistered: (identity) => options.onRegistered?.(entry, identity),
|
|
58
61
|
connection: entry.connection,
|
|
59
62
|
ensureFresh: () => entry.authPlan?.refresh?.ensureFresh().then(() => undefined) ?? Promise.resolve(),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExtensionContext, SessionShutdownEvent, SessionStartEvent } from "../../types.ts";
|
|
1
|
+
import type { ExtensionContext, ExtensionUIContext, SessionShutdownEvent, SessionStartEvent } from "../../types.ts";
|
|
2
2
|
import type { ServerAuthPlan } from "./auth/context.ts";
|
|
3
3
|
import type { McpCachedServerCatalog } from "./catalog-cache.ts";
|
|
4
4
|
import type { ResolvedMcpServer } from "./config-schema.ts";
|
|
@@ -65,6 +65,7 @@ export type McpWireStatusSnapshot = {
|
|
|
65
65
|
readonly servers: readonly McpWireStatusServer[];
|
|
66
66
|
};
|
|
67
67
|
export type McpSessionContext = Pick<ExtensionContext, "cwd" | "isProjectTrusted"> & {
|
|
68
|
+
ui?: ExtensionUIContext;
|
|
68
69
|
mode?: ExtensionContext["mode"];
|
|
69
70
|
/**
|
|
70
71
|
* Session history access, present on the real ExtensionContext. Only
|
|
@@ -89,6 +89,7 @@ export declare class McpService {
|
|
|
89
89
|
setMcpInstructions(instructions: string): void;
|
|
90
90
|
getMcpInstructions(): string;
|
|
91
91
|
setMcpElicitationUiProvider(provider: (() => McpElicitationUi | undefined) | undefined): void;
|
|
92
|
+
bindMcpMrtrPresentation(pi: object, ui: ExtensionUIContext): void;
|
|
92
93
|
getMcpElicitationUi(): McpElicitationUi | undefined;
|
|
93
94
|
isMcpPromptCommandRegistered(name: string): boolean;
|
|
94
95
|
markMcpPromptCommandRegistered(name: string): void;
|