@nexrall/code-core 1.4.71 → 1.4.73
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/agent/agentRegistry.d.ts.map +1 -1
- package/dist/agent/agentRegistry.js +28 -10
- package/dist/agent/agentTypes.d.ts.map +1 -1
- package/dist/agent/agentTypes.js +159 -48
- package/dist/agent/askOnce.d.ts.map +1 -1
- package/dist/agent/askOnce.js +14 -5
- package/dist/agent/backgroundAgents.d.ts.map +1 -1
- package/dist/agent/backgroundAgents.js +22 -8
- package/dist/agent/claimEvidence.d.ts.map +1 -1
- package/dist/agent/claimEvidence.js +2 -1
- package/dist/agent/compaction.d.ts.map +1 -1
- package/dist/agent/compaction.js +31 -10
- package/dist/agent/crossProcessLock.d.ts.map +1 -1
- package/dist/agent/crossProcessLock.js +14 -6
- package/dist/agent/editCompleteness.d.ts.map +1 -1
- package/dist/agent/fileLocks.d.ts.map +1 -1
- package/dist/agent/fileLocks.js +14 -5
- package/dist/agent/flaky.d.ts.map +1 -1
- package/dist/agent/hooks.d.ts.map +1 -1
- package/dist/agent/hooks.js +284 -75
- package/dist/agent/iterationPolicy.d.ts.map +1 -1
- package/dist/agent/iterationPolicy.js +26 -23
- package/dist/agent/lifecycleHost.d.ts.map +1 -1
- package/dist/agent/lifecycleHost.js +35 -11
- package/dist/agent/loop.d.ts +22 -4
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +238 -51
- package/dist/agent/memory.d.ts.map +1 -1
- package/dist/agent/memory.js +13 -7
- package/dist/agent/modelCatalogue.d.ts.map +1 -1
- package/dist/agent/modelCatalogue.js +4 -1
- package/dist/agent/nestedInstructions.d.ts +122 -0
- package/dist/agent/nestedInstructions.d.ts.map +1 -0
- package/dist/agent/nestedInstructions.js +696 -0
- package/dist/agent/peerRegistry.d.ts.map +1 -1
- package/dist/agent/peerRegistry.js +44 -6
- package/dist/agent/peerTransport.d.ts.map +1 -1
- package/dist/agent/peerTransport.js +18 -6
- package/dist/agent/planMode.d.ts.map +1 -1
- package/dist/agent/planMode.js +194 -41
- package/dist/agent/readDedupe.d.ts.map +1 -1
- package/dist/agent/readDedupe.js +3 -1
- package/dist/agent/securityLint.d.ts.map +1 -1
- package/dist/agent/sharedTasks.d.ts.map +1 -1
- package/dist/agent/sharedTasks.js +20 -5
- package/dist/agent/skills.d.ts +79 -0
- package/dist/agent/skills.d.ts.map +1 -1
- package/dist/agent/skills.js +403 -14
- package/dist/agent/subAgentBudget.d.ts.map +1 -1
- package/dist/agent/subTask.d.ts.map +1 -1
- package/dist/agent/subTask.js +87 -37
- package/dist/agent/subTaskSupport.d.ts.map +1 -1
- package/dist/agent/subTaskSupport.js +43 -14
- package/dist/agent/testIntegrity.d.ts.map +1 -1
- package/dist/agent/testIntegrity.js +4 -2
- package/dist/agent/toolDescriptions.d.ts.map +1 -1
- package/dist/agent/toolPrefetch.d.ts.map +1 -1
- package/dist/agent/toolPrefetch.js +15 -11
- package/dist/agent/trust.d.ts.map +1 -1
- package/dist/agent/trust.js +6 -2
- package/dist/agent/worktree.d.ts.map +1 -1
- package/dist/agent/worktree.js +70 -16
- package/dist/agent/worktreeEnforcement.d.ts.map +1 -1
- package/dist/agent/worktreeEnforcement.js +9 -4
- package/dist/api/client.d.ts +6 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +64 -31
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +3 -1
- package/dist/checkpoint/manager.d.ts.map +1 -1
- package/dist/checkpoint/manager.js +22 -7
- package/dist/commands/loader.d.ts.map +1 -1
- package/dist/commands/loader.js +6 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/mcp/client.d.ts +42 -0
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +89 -24
- package/dist/mcp/httpClient.d.ts +24 -1
- package/dist/mcp/httpClient.d.ts.map +1 -1
- package/dist/mcp/httpClient.js +80 -14
- package/dist/mcp/instructions.d.ts +11 -0
- package/dist/mcp/instructions.d.ts.map +1 -0
- package/dist/mcp/instructions.js +42 -0
- package/dist/mcp/manager.d.ts +35 -0
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +135 -24
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +48 -14
- package/dist/mcp/sseClient.d.ts +9 -1
- package/dist/mcp/sseClient.d.ts.map +1 -1
- package/dist/mcp/sseClient.js +43 -10
- package/dist/mcp/stats.d.ts.map +1 -1
- package/dist/permissions/bashClassify.d.ts.map +1 -1
- package/dist/permissions/bashClassify.js +25 -3
- package/dist/permissions/destructive.d.ts.map +1 -1
- package/dist/permissions/destructive.js +7 -2
- package/dist/permissions/destructiveTokens.d.ts.map +1 -1
- package/dist/permissions/destructiveTokens.js +104 -24
- package/dist/permissions/modePolicy.d.ts.map +1 -1
- package/dist/permissions/modePolicy.js +40 -17
- package/dist/permissions/rules.d.ts.map +1 -1
- package/dist/permissions/rules.js +7 -5
- package/dist/plugins/data.d.ts.map +1 -1
- package/dist/plugins/data.js +6 -2
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +18 -7
- package/dist/plugins/installer.d.ts.map +1 -1
- package/dist/plugins/installer.js +17 -10
- package/dist/plugins/sources.d.ts.map +1 -1
- package/dist/plugins/sources.js +9 -3
- package/dist/tools/executor.d.ts.map +1 -1
- package/dist/tools/executor.js +454 -168
- package/dist/tools/sandbox.d.ts.map +1 -1
- package/dist/tools/sandbox.js +5 -1
- package/dist/tools/symbols.d.ts.map +1 -1
- package/dist/tools/symbols.js +30 -8
- package/dist/tools/tsLangService.d.ts.map +1 -1
- package/dist/tools/tsLangService.js +12 -4
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/util/frontmatter.d.ts.map +1 -1
- package/dist/util/miniYaml.d.ts.map +1 -1
- package/dist/util/miniYaml.js +3 -1
- package/package.json +1 -1
package/dist/mcp/client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.McpClient = exports.MCP_ELICITATION_CAPABILITY = void 0;
|
|
3
|
+
exports.McpClient = exports.MCP_PROTOCOL_VERSION = exports.MCP_PROTOCOL_VERSIONS = exports.MCP_ELICITATION_CAPABILITY = void 0;
|
|
4
4
|
exports.flattenResourceContents = flattenResourceContents;
|
|
5
5
|
exports.flattenPromptMessages = flattenPromptMessages;
|
|
6
6
|
exports.elicitationCapability = elicitationCapability;
|
|
@@ -9,16 +9,21 @@ exports.serverRequestReply = serverRequestReply;
|
|
|
9
9
|
const child_process_1 = require("child_process");
|
|
10
10
|
/** Shared parsing of a resources/read reply: text parts joined, binary parts summarised, never inlined. */
|
|
11
11
|
function flattenResourceContents(result, maxChars = 100000) {
|
|
12
|
-
const contents = result
|
|
13
|
-
|
|
12
|
+
const contents = result
|
|
13
|
+
?.contents ?? [];
|
|
14
|
+
const parts = contents
|
|
15
|
+
.map((c) => {
|
|
14
16
|
if (typeof c.text === 'string')
|
|
15
17
|
return c.text;
|
|
16
18
|
if (typeof c.blob === 'string')
|
|
17
19
|
return `[binary resource ${c.uri ?? ''} (${c.mimeType ?? 'unknown type'}, ${Math.round(c.blob.length * 0.75)} bytes) not shown]`;
|
|
18
20
|
return '';
|
|
19
|
-
})
|
|
21
|
+
})
|
|
22
|
+
.filter(Boolean);
|
|
20
23
|
const text = parts.join('\n');
|
|
21
|
-
return text.length > maxChars
|
|
24
|
+
return text.length > maxChars
|
|
25
|
+
? text.slice(0, maxChars) + `\n… [truncated, ${text.length - maxChars} more characters]`
|
|
26
|
+
: text;
|
|
22
27
|
}
|
|
23
28
|
/**
|
|
24
29
|
* Shared parsing of a prompts/get reply: message texts joined in order, non-text
|
|
@@ -28,10 +33,12 @@ function flattenResourceContents(result, maxChars = 100000) {
|
|
|
28
33
|
*/
|
|
29
34
|
function flattenPromptMessages(result, maxChars = 100000) {
|
|
30
35
|
const messages = result?.messages ?? [];
|
|
31
|
-
const parts = messages
|
|
36
|
+
const parts = messages
|
|
37
|
+
.map((m) => {
|
|
32
38
|
const content = m?.content;
|
|
33
39
|
const items = Array.isArray(content) ? content : content ? [content] : [];
|
|
34
|
-
return items
|
|
40
|
+
return items
|
|
41
|
+
.map((c) => {
|
|
35
42
|
const item = c;
|
|
36
43
|
if (item?.type === 'text' && typeof item.text === 'string')
|
|
37
44
|
return item.text;
|
|
@@ -45,13 +52,33 @@ function flattenPromptMessages(result, maxChars = 100000) {
|
|
|
45
52
|
return `[resource prompt content (${item.resource?.uri ?? 'unknown uri'}) not shown]`;
|
|
46
53
|
}
|
|
47
54
|
return '';
|
|
48
|
-
})
|
|
49
|
-
|
|
55
|
+
})
|
|
56
|
+
.filter(Boolean)
|
|
57
|
+
.join('\n');
|
|
58
|
+
})
|
|
59
|
+
.filter(Boolean);
|
|
50
60
|
const text = parts.join('\n\n');
|
|
51
|
-
return text.length > maxChars
|
|
61
|
+
return text.length > maxChars
|
|
62
|
+
? text.slice(0, maxChars) + `\n… [truncated, ${text.length - maxChars} more characters]`
|
|
63
|
+
: text;
|
|
52
64
|
}
|
|
53
65
|
/** Advertised on initialize: we can render both forms. Older servers just see `elicitation` present. */
|
|
54
66
|
exports.MCP_ELICITATION_CAPABILITY = { elicitation: { form: {}, url: {} } };
|
|
67
|
+
// ─── Protocol revisions ───────────────────────────────────────────────────────
|
|
68
|
+
//
|
|
69
|
+
// `initialize` advertises the first entry; the server answers with the revision IT
|
|
70
|
+
// will use. That answer is recorded verbatim — including a revision newer than this
|
|
71
|
+
// list (a 2026-07-28 server): everything after the handshake is gated by the
|
|
72
|
+
// CAPABILITIES we advertise, not by the version string, so an unknown number is
|
|
73
|
+
// informative, not fatal. (Claude Code tolerates exactly this — it shipped a fix for
|
|
74
|
+
// 'calls failing until restart when the server changed its supported version'.)
|
|
75
|
+
//
|
|
76
|
+
// 2025-11-25 is the newest revision whose features this client implements
|
|
77
|
+
// (elicitation incl. URL mode). Do not advertise 2026-07-28 until its requirements
|
|
78
|
+
// are implemented and tested — a version is a promise, not a label.
|
|
79
|
+
exports.MCP_PROTOCOL_VERSIONS = ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'];
|
|
80
|
+
/** What every transport sends as `protocolVersion` in `initialize`. */
|
|
81
|
+
exports.MCP_PROTOCOL_VERSION = exports.MCP_PROTOCOL_VERSIONS[0];
|
|
55
82
|
/**
|
|
56
83
|
* The `capabilities` object for initialize. `bare` (the per-server
|
|
57
84
|
* `bareElicitationCapability` config) sends the older empty shape — the same escape
|
|
@@ -70,8 +97,11 @@ function normalizeElicitationRequest(params) {
|
|
|
70
97
|
mode: p.mode === 'url' || (!p.mode && url) ? 'url' : 'form',
|
|
71
98
|
requestedSchema: schema && typeof schema === 'object' ? schema : undefined,
|
|
72
99
|
url,
|
|
73
|
-
elicitationId: typeof p.elicitationId === 'string'
|
|
74
|
-
|
|
100
|
+
elicitationId: typeof p.elicitationId === 'string'
|
|
101
|
+
? p.elicitationId
|
|
102
|
+
: typeof p.elicitation_id === 'string'
|
|
103
|
+
? p.elicitation_id
|
|
104
|
+
: undefined,
|
|
75
105
|
};
|
|
76
106
|
}
|
|
77
107
|
/**
|
|
@@ -107,10 +137,24 @@ class McpClient {
|
|
|
107
137
|
this._buf = '';
|
|
108
138
|
this._tools = [];
|
|
109
139
|
this._elicitationHandler = null;
|
|
140
|
+
this._notificationHandler = null;
|
|
110
141
|
this.name = name;
|
|
111
142
|
}
|
|
112
|
-
get tools() {
|
|
113
|
-
|
|
143
|
+
get tools() {
|
|
144
|
+
return this._tools;
|
|
145
|
+
}
|
|
146
|
+
get protocolVersion() {
|
|
147
|
+
return this._protocolVersion;
|
|
148
|
+
}
|
|
149
|
+
get instructions() {
|
|
150
|
+
return this._instructions;
|
|
151
|
+
}
|
|
152
|
+
setElicitationHandler(handler) {
|
|
153
|
+
this._elicitationHandler = handler;
|
|
154
|
+
}
|
|
155
|
+
setNotificationHandler(handler) {
|
|
156
|
+
this._notificationHandler = handler;
|
|
157
|
+
}
|
|
114
158
|
async connect() {
|
|
115
159
|
if (!this.config.command)
|
|
116
160
|
throw new Error(`MCP server "${this.name}" has no command (stdio transport requires one).`);
|
|
@@ -136,16 +180,29 @@ class McpClient {
|
|
|
136
180
|
this._proc.on('exit', () => {
|
|
137
181
|
this._rejectAll(new Error(`MCP server "${this.name}" exited unexpectedly`));
|
|
138
182
|
});
|
|
139
|
-
// Handshake: initialize
|
|
140
|
-
|
|
141
|
-
|
|
183
|
+
// Handshake: initialize. The reply carries the revision the server will use
|
|
184
|
+
// and often `instructions` — both recorded; see MCP_PROTOCOL_VERSIONS for
|
|
185
|
+
// why an unknown counter-offer is accepted rather than treated as an error.
|
|
186
|
+
const init = (await this._request('initialize', {
|
|
187
|
+
protocolVersion: exports.MCP_PROTOCOL_VERSION,
|
|
142
188
|
capabilities: elicitationCapability(this.config.bareElicitationCapability),
|
|
143
189
|
clientInfo: { name: 'nexrall-code', version: '1.0' },
|
|
144
|
-
});
|
|
190
|
+
}));
|
|
191
|
+
this._protocolVersion =
|
|
192
|
+
typeof init?.protocolVersion === 'string' && init.protocolVersion ? init.protocolVersion : undefined;
|
|
193
|
+
this._instructions =
|
|
194
|
+
typeof init?.instructions === 'string' && init.instructions.trim() ? init.instructions : undefined;
|
|
145
195
|
// Send initialized notification (no response expected)
|
|
146
196
|
this._notify('notifications/initialized');
|
|
147
|
-
|
|
148
|
-
|
|
197
|
+
await this.refreshTools();
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Re-fetch `tools/list`. Called by the manager when a server announces
|
|
201
|
+
* `notifications/tools/list_changed`; on failure the OLD table stays in place
|
|
202
|
+
* (a transient error must not empty the toolset).
|
|
203
|
+
*/
|
|
204
|
+
async refreshTools() {
|
|
205
|
+
const result = (await this._request('tools/list', {}));
|
|
149
206
|
this._tools = result?.tools ?? [];
|
|
150
207
|
}
|
|
151
208
|
async listResources() {
|
|
@@ -176,7 +233,7 @@ class McpClient {
|
|
|
176
233
|
return flattenPromptMessages(await this._request('prompts/get', params));
|
|
177
234
|
}
|
|
178
235
|
async callTool(name, args) {
|
|
179
|
-
const result = await this._request('tools/call', { name, arguments: args });
|
|
236
|
+
const result = (await this._request('tools/call', { name, arguments: args }));
|
|
180
237
|
if (!result)
|
|
181
238
|
return '';
|
|
182
239
|
const text = (result.content ?? [])
|
|
@@ -192,7 +249,9 @@ class McpClient {
|
|
|
192
249
|
try {
|
|
193
250
|
this._proc.kill('SIGTERM');
|
|
194
251
|
}
|
|
195
|
-
catch {
|
|
252
|
+
catch {
|
|
253
|
+
/* ignore */
|
|
254
|
+
}
|
|
196
255
|
this._proc = null;
|
|
197
256
|
}
|
|
198
257
|
this._rejectAll(new Error(`MCP server "${this.name}" disconnected`));
|
|
@@ -234,8 +293,14 @@ class McpClient {
|
|
|
234
293
|
void this._handleServerRequest(msg.id, msg.method, msg.params);
|
|
235
294
|
return;
|
|
236
295
|
}
|
|
237
|
-
if (msg.id == null)
|
|
238
|
-
|
|
296
|
+
if (msg.id == null) {
|
|
297
|
+
// Server-initiated notification (list_changed for tools/prompts/resources).
|
|
298
|
+
// Forwarded to the manager, which decides what a method invalidates.
|
|
299
|
+
if (typeof msg.method === 'string') {
|
|
300
|
+
this._notificationHandler?.(msg.method, msg.params);
|
|
301
|
+
}
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
239
304
|
const pending = this._pending.get(msg.id);
|
|
240
305
|
if (!pending)
|
|
241
306
|
return;
|
package/dist/mcp/httpClient.d.ts
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
import type { McpServerConfig, McpToolDefinition, McpTransport, McpResource, McpPrompt, McpElicitationHandler } from './client';
|
|
1
|
+
import type { McpServerConfig, McpToolDefinition, McpTransport, McpResource, McpPrompt, McpElicitationHandler, McpNotificationHandler } from './client';
|
|
2
|
+
/**
|
|
3
|
+
* The Bearer parameters of a `WWW-Authenticate` challenge, as far as they change
|
|
4
|
+
* behaviour. `error="insufficient_scope"` + `scope="a b"` is a token that WORKS but
|
|
5
|
+
* lacks permissions — a different user-facing story from a plain 401, and CC draws
|
|
6
|
+
* the same line (changelog 2.1.288 line 8, 1231). Unquoted values (`scope=read`)
|
|
7
|
+
* are legal in some hand-rolled servers, hence the fallback branch.
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseOAuthChallenge(wwwAuthenticate: string): {
|
|
10
|
+
insufficientScope: boolean;
|
|
11
|
+
scope?: string;
|
|
12
|
+
};
|
|
2
13
|
/** Thrown when a remote MCP server replies 401 — the caller should run the OAuth flow. */
|
|
3
14
|
export declare class McpOAuthRequiredError extends Error {
|
|
4
15
|
readonly serverName: string;
|
|
5
16
|
readonly serverUrl: string;
|
|
6
17
|
readonly wwwAuthenticate: string;
|
|
18
|
+
/** The permissions the server says the token is missing (empty for a plain 401). */
|
|
19
|
+
readonly missingScope: string | undefined;
|
|
20
|
+
/** True when the token is valid but under-scoped — sign-in must ask for MORE, not just again. */
|
|
21
|
+
readonly insufficientScope: boolean;
|
|
7
22
|
constructor(serverName: string, serverUrl: string, wwwAuthenticate: string);
|
|
8
23
|
}
|
|
9
24
|
export declare class McpHttpClient implements McpTransport {
|
|
@@ -12,10 +27,18 @@ export declare class McpHttpClient implements McpTransport {
|
|
|
12
27
|
private _tools;
|
|
13
28
|
private _sessionId;
|
|
14
29
|
private _elicitationHandler;
|
|
30
|
+
private _notificationHandler;
|
|
31
|
+
private _protocolVersion;
|
|
32
|
+
private _instructions;
|
|
15
33
|
readonly name: string;
|
|
16
34
|
constructor(name: string, config: McpServerConfig);
|
|
17
35
|
get tools(): McpToolDefinition[];
|
|
36
|
+
get protocolVersion(): string | undefined;
|
|
37
|
+
get instructions(): string | undefined;
|
|
18
38
|
setElicitationHandler(handler: McpElicitationHandler | null): void;
|
|
39
|
+
setNotificationHandler(handler: McpNotificationHandler | null): void;
|
|
40
|
+
/** Re-fetch `tools/list` (see McpClient.refreshTools for the failure rule). */
|
|
41
|
+
refreshTools(): Promise<void>;
|
|
19
42
|
connect(): Promise<void>;
|
|
20
43
|
listResources(): Promise<McpResource[]>;
|
|
21
44
|
readResource(uri: string): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"httpClient.d.ts","sourceRoot":"","sources":["../../src/mcp/httpClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"httpClient.d.ts","sourceRoot":"","sources":["../../src/mcp/httpClient.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,SAAS,EACT,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,UAAU,CAAC;AAqBlB;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG;IAAE,iBAAiB,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAS3G;AAED,0FAA0F;AAC1F,qBAAa,qBAAsB,SAAQ,KAAK;aAO5B,UAAU,EAAE,MAAM;aAClB,SAAS,EAAE,MAAM;aACjB,eAAe,EAAE,MAAM;IARzC,oFAAoF;IACpF,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,iGAAiG;IACjG,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;gBAGlB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM;CAY1C;AAED,qBAAa,aAAc,YAAW,YAAY;IAY9C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAXzB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,mBAAmB,CAAsC;IACjE,OAAO,CAAC,oBAAoB,CAAuC;IACnE,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,aAAa,CAAqB;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGpB,IAAI,EAAE,MAAM,EACK,MAAM,EAAE,eAAe;IAK1C,IAAI,KAAK,IAAI,iBAAiB,EAAE,CAE/B;IAED,IAAI,eAAe,IAAI,MAAM,GAAG,SAAS,CAExC;IAED,IAAI,YAAY,IAAI,MAAM,GAAG,SAAS,CAErC;IAED,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,GAAG,IAAI;IAIlE,sBAAsB,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,GAAG,IAAI;IAIpE,+EAA+E;IACzE,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAexB,aAAa,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IASvC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI1C,WAAW,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IASnC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAMtE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAc5E,UAAU,IAAI,IAAI;YAeJ,IAAI;YAMJ,OAAO;YAKP,KAAK;YA2BL,cAAc;IAkB5B;;;;;;OAMG;YACW,WAAW;IAoFzB,8FAA8F;IAC9F,OAAO,CAAC,oBAAoB;CAQ7B"}
|
package/dist/mcp/httpClient.js
CHANGED
|
@@ -4,17 +4,40 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.McpHttpClient = exports.McpOAuthRequiredError = void 0;
|
|
7
|
+
exports.parseOAuthChallenge = parseOAuthChallenge;
|
|
7
8
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
8
9
|
const client_1 = require("./client");
|
|
9
10
|
const REQUEST_TIMEOUT_MS = 30000;
|
|
11
|
+
/**
|
|
12
|
+
* The Bearer parameters of a `WWW-Authenticate` challenge, as far as they change
|
|
13
|
+
* behaviour. `error="insufficient_scope"` + `scope="a b"` is a token that WORKS but
|
|
14
|
+
* lacks permissions — a different user-facing story from a plain 401, and CC draws
|
|
15
|
+
* the same line (changelog 2.1.288 line 8, 1231). Unquoted values (`scope=read`)
|
|
16
|
+
* are legal in some hand-rolled servers, hence the fallback branch.
|
|
17
|
+
*/
|
|
18
|
+
function parseOAuthChallenge(wwwAuthenticate) {
|
|
19
|
+
const params = {};
|
|
20
|
+
for (const m of (wwwAuthenticate || '').matchAll(/([a-zA-Z_][\w-]*)\s*=\s*(?:"([^"]*)"|([^\s,]+))/g)) {
|
|
21
|
+
params[m[1].toLowerCase()] = m[2] ?? m[3] ?? '';
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
insufficientScope: params.error === 'insufficient_scope',
|
|
25
|
+
scope: params.scope || undefined,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
10
28
|
/** Thrown when a remote MCP server replies 401 — the caller should run the OAuth flow. */
|
|
11
29
|
class McpOAuthRequiredError extends Error {
|
|
12
30
|
constructor(serverName, serverUrl, wwwAuthenticate) {
|
|
13
|
-
|
|
31
|
+
const ch = parseOAuthChallenge(wwwAuthenticate);
|
|
32
|
+
super(ch.insufficientScope
|
|
33
|
+
? `MCP server "${serverName}" needs additional permissions${ch.scope ? ` (missing scope: ${ch.scope})` : ''}. Run /mcp auth ${serverName} to re-authorize.`
|
|
34
|
+
: `MCP server "${serverName}" requires authentication — run /mcp auth ${serverName} to sign in.`);
|
|
14
35
|
this.serverName = serverName;
|
|
15
36
|
this.serverUrl = serverUrl;
|
|
16
37
|
this.wwwAuthenticate = wwwAuthenticate;
|
|
17
38
|
this.name = 'McpOAuthRequiredError';
|
|
39
|
+
this.missingScope = ch.scope;
|
|
40
|
+
this.insufficientScope = ch.insufficientScope;
|
|
18
41
|
}
|
|
19
42
|
}
|
|
20
43
|
exports.McpOAuthRequiredError = McpOAuthRequiredError;
|
|
@@ -25,23 +48,43 @@ class McpHttpClient {
|
|
|
25
48
|
this._tools = [];
|
|
26
49
|
this._sessionId = null;
|
|
27
50
|
this._elicitationHandler = null;
|
|
51
|
+
this._notificationHandler = null;
|
|
28
52
|
this.name = name;
|
|
29
53
|
}
|
|
30
54
|
get tools() {
|
|
31
55
|
return this._tools;
|
|
32
56
|
}
|
|
33
|
-
|
|
57
|
+
get protocolVersion() {
|
|
58
|
+
return this._protocolVersion;
|
|
59
|
+
}
|
|
60
|
+
get instructions() {
|
|
61
|
+
return this._instructions;
|
|
62
|
+
}
|
|
63
|
+
setElicitationHandler(handler) {
|
|
64
|
+
this._elicitationHandler = handler;
|
|
65
|
+
}
|
|
66
|
+
setNotificationHandler(handler) {
|
|
67
|
+
this._notificationHandler = handler;
|
|
68
|
+
}
|
|
69
|
+
/** Re-fetch `tools/list` (see McpClient.refreshTools for the failure rule). */
|
|
70
|
+
async refreshTools() {
|
|
71
|
+
const res = (await this._rpc('tools/list', {}));
|
|
72
|
+
this._tools = res?.tools ?? [];
|
|
73
|
+
}
|
|
34
74
|
async connect() {
|
|
35
75
|
if (!this.config.url)
|
|
36
76
|
throw new Error(`MCP server "${this.name}" has no url (http/sse transport requires one).`);
|
|
37
|
-
await this._rpc('initialize', {
|
|
38
|
-
protocolVersion:
|
|
77
|
+
const init = (await this._rpc('initialize', {
|
|
78
|
+
protocolVersion: client_1.MCP_PROTOCOL_VERSION,
|
|
39
79
|
capabilities: (0, client_1.elicitationCapability)(this.config.bareElicitationCapability),
|
|
40
80
|
clientInfo: { name: 'nexrall-code', version: '1.0' },
|
|
41
|
-
});
|
|
81
|
+
}));
|
|
82
|
+
this._protocolVersion =
|
|
83
|
+
typeof init?.protocolVersion === 'string' && init.protocolVersion ? init.protocolVersion : undefined;
|
|
84
|
+
this._instructions =
|
|
85
|
+
typeof init?.instructions === 'string' && init.instructions.trim() ? init.instructions : undefined;
|
|
42
86
|
await this._notify('notifications/initialized');
|
|
43
|
-
|
|
44
|
-
this._tools = res?.tools ?? [];
|
|
87
|
+
await this.refreshTools();
|
|
45
88
|
}
|
|
46
89
|
async listResources() {
|
|
47
90
|
try {
|
|
@@ -88,7 +131,9 @@ class McpHttpClient {
|
|
|
88
131
|
(0, node_fetch_1.default)(this.config.url, {
|
|
89
132
|
method: 'DELETE',
|
|
90
133
|
headers: { 'Mcp-Session-Id': this._sessionId, ...(this.config.headers ?? {}) },
|
|
91
|
-
}).catch(() => {
|
|
134
|
+
}).catch(() => {
|
|
135
|
+
/* ignore */
|
|
136
|
+
});
|
|
92
137
|
}
|
|
93
138
|
this._sessionId = null;
|
|
94
139
|
}
|
|
@@ -162,6 +207,13 @@ class McpHttpClient {
|
|
|
162
207
|
this._answerServerRequest(msg.id, msg.method, msg.params);
|
|
163
208
|
return;
|
|
164
209
|
}
|
|
210
|
+
if (msg.id == null) {
|
|
211
|
+
// Server-initiated notification interleaved with our response stream.
|
|
212
|
+
if (typeof msg.method === 'string') {
|
|
213
|
+
this._notificationHandler?.(msg.method, msg.params);
|
|
214
|
+
}
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
165
217
|
if (msg.id !== id)
|
|
166
218
|
return;
|
|
167
219
|
if (msg.error)
|
|
@@ -183,7 +235,9 @@ class McpHttpClient {
|
|
|
183
235
|
try {
|
|
184
236
|
handle(JSON.parse(data));
|
|
185
237
|
}
|
|
186
|
-
catch {
|
|
238
|
+
catch {
|
|
239
|
+
/* comment/ping frame */
|
|
240
|
+
}
|
|
187
241
|
};
|
|
188
242
|
try {
|
|
189
243
|
for await (const chunk of body) {
|
|
@@ -208,22 +262,32 @@ class McpHttpClient {
|
|
|
208
262
|
}
|
|
209
263
|
flush();
|
|
210
264
|
}
|
|
211
|
-
catch {
|
|
265
|
+
catch {
|
|
266
|
+
/* a torn-down stream is not itself an error; the checks below decide */
|
|
267
|
+
}
|
|
212
268
|
try {
|
|
213
269
|
await body.cancel?.();
|
|
214
270
|
}
|
|
215
|
-
catch {
|
|
271
|
+
catch {
|
|
272
|
+
/* best-effort */
|
|
273
|
+
}
|
|
216
274
|
}
|
|
217
275
|
else {
|
|
218
276
|
const text = await resp.text();
|
|
219
277
|
for (const frame of text.split(/\r?\n\r?\n/)) {
|
|
220
|
-
const data = frame
|
|
278
|
+
const data = frame
|
|
279
|
+
.split(/\r?\n/)
|
|
280
|
+
.filter((l) => l.startsWith('data:'))
|
|
281
|
+
.map((l) => l.slice(5).trim())
|
|
282
|
+
.join('\n');
|
|
221
283
|
if (!data)
|
|
222
284
|
continue;
|
|
223
285
|
try {
|
|
224
286
|
handle(JSON.parse(data));
|
|
225
287
|
}
|
|
226
|
-
catch {
|
|
288
|
+
catch {
|
|
289
|
+
/* skip non-JSON frames */
|
|
290
|
+
}
|
|
227
291
|
}
|
|
228
292
|
}
|
|
229
293
|
if (state.failure)
|
|
@@ -237,7 +301,9 @@ class McpHttpClient {
|
|
|
237
301
|
void (async () => {
|
|
238
302
|
const reply = await (0, client_1.serverRequestReply)(this.name, this._elicitationHandler, method, params);
|
|
239
303
|
await this._post({ jsonrpc: '2.0', id, ...reply });
|
|
240
|
-
})().catch(() => {
|
|
304
|
+
})().catch(() => {
|
|
305
|
+
/* stream may be gone; the server times the request out itself */
|
|
306
|
+
});
|
|
241
307
|
}
|
|
242
308
|
}
|
|
243
309
|
exports.McpHttpClient = McpHttpClient;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const MCP_INSTRUCTIONS_PER_SERVER = 2000;
|
|
2
|
+
export declare const MCP_INSTRUCTIONS_TOTAL = 8000;
|
|
3
|
+
/**
|
|
4
|
+
* Render the block, or null when there is nothing to inject — callers join the
|
|
5
|
+
* result with the project brief, and a null must not leave an empty section behind.
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatMcpInstructions(entries: Array<{
|
|
8
|
+
server: string;
|
|
9
|
+
instructions: string;
|
|
10
|
+
}>): string | null;
|
|
11
|
+
//# sourceMappingURL=instructions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/mcp/instructions.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAChD,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,GAAG,IAAI,CAkB7G"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The `initialize.instructions` prompt block — a server's own reference notes,
|
|
3
|
+
// injected into the same system-prompt channel as nexrallMd (loop.ts composes it
|
|
4
|
+
// per request, so a server connected or enabled mid-session contributes on the
|
|
5
|
+
// very next call without rebuilding the session brief).
|
|
6
|
+
//
|
|
7
|
+
// Kept as a pure function in its own module because the caps are policy, not
|
|
8
|
+
// plumbing: the strings come from a third-party process, so one server may add
|
|
9
|
+
// MCP_INSTRUCTIONS_PER_SERVER characters and all servers together
|
|
10
|
+
// MCP_INSTRUCTIONS_TOTAL — beyond that the note is truncated (visibly, with a
|
|
11
|
+
// marker) or omitted, rather than allowed to crowd out the real project brief.
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.MCP_INSTRUCTIONS_TOTAL = exports.MCP_INSTRUCTIONS_PER_SERVER = void 0;
|
|
14
|
+
exports.formatMcpInstructions = formatMcpInstructions;
|
|
15
|
+
exports.MCP_INSTRUCTIONS_PER_SERVER = 2000;
|
|
16
|
+
exports.MCP_INSTRUCTIONS_TOTAL = 8000;
|
|
17
|
+
/**
|
|
18
|
+
* Render the block, or null when there is nothing to inject — callers join the
|
|
19
|
+
* result with the project brief, and a null must not leave an empty section behind.
|
|
20
|
+
*/
|
|
21
|
+
function formatMcpInstructions(entries) {
|
|
22
|
+
const parts = [];
|
|
23
|
+
let used = 0;
|
|
24
|
+
for (const e of entries) {
|
|
25
|
+
let text = e.instructions.trim();
|
|
26
|
+
if (!text)
|
|
27
|
+
continue;
|
|
28
|
+
if (text.length > exports.MCP_INSTRUCTIONS_PER_SERVER) {
|
|
29
|
+
text = text.slice(0, exports.MCP_INSTRUCTIONS_PER_SERVER) + '\n[truncated]';
|
|
30
|
+
}
|
|
31
|
+
if (used + text.length > exports.MCP_INSTRUCTIONS_TOTAL) {
|
|
32
|
+
parts.push(`(more servers omitted — the ${exports.MCP_INSTRUCTIONS_TOTAL}-character budget was reached)`);
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
used += text.length;
|
|
36
|
+
parts.push(`## ${e.server}\n${text}`);
|
|
37
|
+
}
|
|
38
|
+
if (!parts.length)
|
|
39
|
+
return null;
|
|
40
|
+
return ['# MCP server instructions', '', ...parts].join('\n');
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=instructions.js.map
|
package/dist/mcp/manager.d.ts
CHANGED
|
@@ -37,6 +37,15 @@ export declare class McpManager {
|
|
|
37
37
|
* connectAll/enable. Pass null to restore auto-decline.
|
|
38
38
|
*/
|
|
39
39
|
setElicitationHandler(handler: McpElicitationHandler | null): void;
|
|
40
|
+
/**
|
|
41
|
+
* Route server→client notifications for one client: `tools/list_changed` re-fetches
|
|
42
|
+
* the tool table and rebuilds the prefixed map in place (new tools appear on the next
|
|
43
|
+
* turn — no restart), `prompts/list_changed` drops the cached prompt list. A failed
|
|
44
|
+
* refresh keeps the OLD table: a transient error must not empty the toolset.
|
|
45
|
+
*/
|
|
46
|
+
private _wireNotifications;
|
|
47
|
+
/** Replace one server's entries in the prefixed tool map with its current list. */
|
|
48
|
+
private _refreshToolMap;
|
|
40
49
|
/** Pick the transport for a server config: stdio (command), Streamable HTTP, or legacy SSE. */
|
|
41
50
|
private static makeClient;
|
|
42
51
|
/** Load config from ~/.nexrall/mcp.json, <workDir>/.nexrall/mcp.json, and plugin mcp.json files. */
|
|
@@ -95,6 +104,15 @@ export declare class McpManager {
|
|
|
95
104
|
isMcpTool(name: string): boolean;
|
|
96
105
|
get serverNames(): string[];
|
|
97
106
|
get toolCount(): number;
|
|
107
|
+
/**
|
|
108
|
+
* Names of configured servers whose entry sets `alwaysLoad: true` (CC parity).
|
|
109
|
+
* The agent loop sends this per request; the backend keeps those servers' tools
|
|
110
|
+
* out of BOTH deferral paths (tool-search `defer_loading` and the cap selector's
|
|
111
|
+
* droppable set). Config-level — a server that failed to connect still contributes
|
|
112
|
+
* an inert name, since it sends no tools to protect. Sorted because the list rides
|
|
113
|
+
* in the request body, which is part of the tools-cache key.
|
|
114
|
+
*/
|
|
115
|
+
alwaysLoadServers(): string[];
|
|
98
116
|
private static transportOf;
|
|
99
117
|
/** Returns per-server status for UI display, including failed / auth-required / disabled. */
|
|
100
118
|
getStatus(): Array<{
|
|
@@ -105,9 +123,26 @@ export declare class McpManager {
|
|
|
105
123
|
disabled: boolean;
|
|
106
124
|
error?: string;
|
|
107
125
|
needsAuth?: boolean;
|
|
126
|
+
/** Permissions the server says are missing, when `needsAuth` came from an insufficient_scope 401. */
|
|
127
|
+
missingScope?: string;
|
|
128
|
+
/** Revision the server agreed to in `initialize` (connected servers only). */
|
|
129
|
+
protocolVersion?: string;
|
|
130
|
+
/** mcp.json entry sets `alwaysLoad: true` — its tools resist the backend tool cap. */
|
|
131
|
+
alwaysLoad: boolean;
|
|
108
132
|
}>;
|
|
109
133
|
/** The WWW-Authenticate challenge a server returned on 401 (empty if none/unknown). */
|
|
110
134
|
authChallenge(name: string): string;
|
|
135
|
+
/** Permissions an auth-required server says are missing ('' when unknown/plain 401). */
|
|
136
|
+
missingScope(name: string): string;
|
|
137
|
+
/**
|
|
138
|
+
* `initialize.instructions` from every connected server that sent one — static
|
|
139
|
+
* reference notes (workflow rules, repo layout) the conversation should carry.
|
|
140
|
+
* The caller decides where they go; ordering is by server name for stable output.
|
|
141
|
+
*/
|
|
142
|
+
serverInstructions(): Array<{
|
|
143
|
+
server: string;
|
|
144
|
+
instructions: string;
|
|
145
|
+
}>;
|
|
111
146
|
/** True when the user has switched this server off for the session. */
|
|
112
147
|
isDisabled(name: string): boolean;
|
|
113
148
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/mcp/manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAa,eAAe,EAAE,iBAAiB,EAAgB,WAAW,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC/G,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAItD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIpC,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAGD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAID,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAmC;IAEnD,OAAO,CAAC,QAAQ,CAA6B;IAI7C,OAAO,CAAC,YAAY,CAAkC;IAEtD,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,OAAO,CAA6B;IAE5C,OAAO,CAAC,UAAU,CAA6B;IAG/C,OAAO,CAAC,SAAS,CAAqB;IACtC,wFAAwF;IACxF,QAAQ,CAAC,KAAK,YAAmB;IAGjC,OAAO,CAAC,mBAAmB,CAAsC;IAEjE;;;;OAIG;IACH,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,GAAG,IAAI;IAKlE,+FAA+F;IAC/F,OAAO,CAAC,MAAM,CAAC,UAAU;IAMzB,oGAAoG;IACpG,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/mcp/manager.ts"],"names":[],"mappings":"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"}
|