@wrongstack/mcp 1.0.2 → 1.0.4
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/constants.d.ts +29 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +37 -13
- package/dist/server.d.ts +2 -0
- package/dist/transport-base.d.ts +2 -0
- package/package.json +2 -2
package/dist/constants.d.ts
CHANGED
|
@@ -6,9 +6,36 @@
|
|
|
6
6
|
* - Reconnect parameters can be overridden via config in the future
|
|
7
7
|
* - No scattered magic values across multiple files
|
|
8
8
|
*/
|
|
9
|
+
/**
|
|
10
|
+
* Protocol revisions this package actually implements, newest first.
|
|
11
|
+
*
|
|
12
|
+
* Deliberately conservative: a revision belongs here only once its wire
|
|
13
|
+
* requirements are met, because the version we send in `initialize` is a
|
|
14
|
+
* promise about what the peer may then use. WrongStack speaks the 2024-11-05
|
|
15
|
+
* shape — tools, resources, prompts, sampling — and does not implement the
|
|
16
|
+
* additions of later revisions (elicitation, structured tool output, resource
|
|
17
|
+
* links), so listing one of those would advertise capabilities that are not
|
|
18
|
+
* there.
|
|
19
|
+
*
|
|
20
|
+
* Adding a revision: implement its additions, then put it at the FRONT.
|
|
21
|
+
* `PROTOCOL_VERSION` follows automatically, and the negotiation below starts
|
|
22
|
+
* accepting a peer that asks for it.
|
|
23
|
+
*/
|
|
24
|
+
export declare const SUPPORTED_PROTOCOL_VERSIONS: readonly string[];
|
|
25
|
+
/**
|
|
26
|
+
* Pick the version to answer an `initialize` with.
|
|
27
|
+
*
|
|
28
|
+
* The spec's rule: echo what the peer asked for when it is supported,
|
|
29
|
+
* otherwise reply with our own latest and let the peer decide whether it can
|
|
30
|
+
* continue. Before this existed the server ignored the request entirely and
|
|
31
|
+
* always answered `2024-11-05`, so a peer that asked for a newer revision was
|
|
32
|
+
* told it had been granted nothing of the sort — silently, with no way to see
|
|
33
|
+
* the mismatch.
|
|
34
|
+
*/
|
|
35
|
+
export declare function negotiateProtocolVersion(requested: unknown): string;
|
|
9
36
|
export declare const MCP_CONSTANTS: Readonly<{
|
|
10
|
-
/** MCP protocol version advertised during handshake. */
|
|
11
|
-
readonly PROTOCOL_VERSION:
|
|
37
|
+
/** MCP protocol version advertised during handshake: the newest we implement. */
|
|
38
|
+
readonly PROTOCOL_VERSION: string;
|
|
12
39
|
/** Identity announced to MCP servers during `initialize`. */
|
|
13
40
|
readonly CLIENT_INFO: Readonly<{
|
|
14
41
|
name: "wrongstack";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { authorizationHeaderForToken, authorizationServerMetadataUrls, canonicalMcpResource, createMcpAuthorizationRequest, discoverMcpAuthorization, exchangeMcpAuthorizationCode, type MCPAccessToken, type MCPAuthorizationChallenge, type MCPAuthorizationContext, type MCPAuthorizationDiscoveryOptions, type MCPAuthorizationDiscoveryResult, type MCPAuthorizationJsonFetcher, type MCPAuthorizationProvider, type MCPAuthorizationRequestOptions, type MCPAuthorizationServerMetadata, type MCPAuthorizationSession, type MCPProtectedResourceMetadata, type MCPTokenExchangeOptions, type MCPTokenRefreshOptions, type MCPTokenSet, parseAuthorizationServerMetadata, parseMcpAuthorizationCallback, parseMcpBearerChallenge, parseProtectedResourceMetadata, protectedResourceMetadataUrls, refreshMcpAccessToken, validateMcpAuthorizationServerMetadata, } from './authorization.js';
|
|
2
2
|
export { type MCPAuthorizationCompleteInput, MCPAuthorizationManager, type MCPAuthorizationManagerOptions, type MCPAuthorizationStartInput, type MCPAuthorizationStartResult, type MCPAuthorizationStatus, } from './authorization-manager.js';
|
|
3
3
|
export { MCPClient, type MCPClientOptions, type MCPListChangedListener, type MCPPageOptions, type MCPRequestOptions, type Transport, } from './client.js';
|
|
4
|
-
export { MCP_CONSTANTS } from './constants.js';
|
|
4
|
+
export { MCP_CONSTANTS, negotiateProtocolVersion, SUPPORTED_PROTOCOL_VERSIONS, } from './constants.js';
|
|
5
5
|
export { DEFAULT_MCP_INSERTION_MAX_BYTES, DEFAULT_MCP_RESOURCE_SCHEMES, type MCPContentProvenance, type MCPInsertionPolicy, type MCPPromptInsertion, type MCPResourceInsertion, preparePromptInsertion, prepareResourceInsertion, } from './content-selection.js';
|
|
6
6
|
export type { ConnectionState, JsonRpcResponse, MCPTool, ToolCallResult, } from './contracts.js';
|
|
7
7
|
export { addMcp, disableMcp, discoverMcp, enableMcp, listMcp, MCP_ENV_MASK, type McpManageDeps, type McpOpResult, type McpServerInfo, type McpServerInput, removeMcp, restartMcp, updateMcp, } from './manage.js';
|
package/dist/index.js
CHANGED
|
@@ -875,9 +875,16 @@ function parseEmptyResult(value) {
|
|
|
875
875
|
}
|
|
876
876
|
|
|
877
877
|
// src/constants.ts
|
|
878
|
+
var SUPPORTED_PROTOCOL_VERSIONS = Object.freeze(["2024-11-05"]);
|
|
879
|
+
function negotiateProtocolVersion(requested) {
|
|
880
|
+
if (typeof requested === "string" && SUPPORTED_PROTOCOL_VERSIONS.includes(requested)) {
|
|
881
|
+
return requested;
|
|
882
|
+
}
|
|
883
|
+
return MCP_CONSTANTS.PROTOCOL_VERSION;
|
|
884
|
+
}
|
|
878
885
|
var MCP_CONSTANTS = Object.freeze({
|
|
879
|
-
/** MCP protocol version advertised during handshake. */
|
|
880
|
-
PROTOCOL_VERSION:
|
|
886
|
+
/** MCP protocol version advertised during handshake: the newest we implement. */
|
|
887
|
+
PROTOCOL_VERSION: SUPPORTED_PROTOCOL_VERSIONS[0],
|
|
881
888
|
/** Identity announced to MCP servers during `initialize`. */
|
|
882
889
|
CLIENT_INFO: Object.freeze({
|
|
883
890
|
name: "wrongstack",
|
|
@@ -1262,7 +1269,7 @@ import { Agent as UndiciAgent, fetch as undiciFetch } from "undici";
|
|
|
1262
1269
|
import * as dns2 from "node:dns/promises";
|
|
1263
1270
|
import * as net2 from "node:net";
|
|
1264
1271
|
import { ConfigError } from "@wrongstack/core/types";
|
|
1265
|
-
import { isPrivateIPv4 as isPrivateIPv42, isPrivateIPv6 as isPrivateIPv62 } from "@wrongstack/core/utils";
|
|
1272
|
+
import { embeddedIPv4, expandIPv6, isPrivateIPv4 as isPrivateIPv42, isPrivateIPv6 as isPrivateIPv62 } from "@wrongstack/core/utils";
|
|
1266
1273
|
function isTlsUnsafeAllowed() {
|
|
1267
1274
|
return process.env["WRONGSTACK_UNSAFE_MCP_TLS"] === "1";
|
|
1268
1275
|
}
|
|
@@ -1351,6 +1358,11 @@ function classifyTransportAddress(address, family) {
|
|
|
1351
1358
|
}
|
|
1352
1359
|
return "blocked";
|
|
1353
1360
|
}
|
|
1361
|
+
const groups = expandIPv6(v6);
|
|
1362
|
+
if (groups !== null) {
|
|
1363
|
+
const embedded = embeddedIPv4(groups);
|
|
1364
|
+
if (embedded !== void 0) return classifyTransportAddress(embedded, 4);
|
|
1365
|
+
}
|
|
1354
1366
|
return isPrivateIPv62(v6) ? "private" : "public";
|
|
1355
1367
|
}
|
|
1356
1368
|
return "blocked";
|
|
@@ -1425,6 +1437,9 @@ function makeAbortError(method) {
|
|
|
1425
1437
|
err.name = "AbortError";
|
|
1426
1438
|
return err;
|
|
1427
1439
|
}
|
|
1440
|
+
function nextJsonRpcId(id) {
|
|
1441
|
+
return id >= Number.MAX_SAFE_INTEGER ? 1 : id + 1;
|
|
1442
|
+
}
|
|
1428
1443
|
function createTimeoutSignal(parent, timeoutMs) {
|
|
1429
1444
|
const ctrl = new AbortController();
|
|
1430
1445
|
const onAbort = () => ctrl.abort(parent?.reason);
|
|
@@ -1807,7 +1822,9 @@ var SSETransport = class extends BaseHTTPTransport {
|
|
|
1807
1822
|
super(opts, "SSETransport");
|
|
1808
1823
|
}
|
|
1809
1824
|
genId() {
|
|
1810
|
-
|
|
1825
|
+
const id = this._nextId;
|
|
1826
|
+
this._nextId = nextJsonRpcId(id);
|
|
1827
|
+
return id;
|
|
1811
1828
|
}
|
|
1812
1829
|
/** Refresh tool list when server sends notifications/tools/list_changed. */
|
|
1813
1830
|
async handleToolsListChanged() {
|
|
@@ -2121,7 +2138,9 @@ var StreamableHTTPTransport = class _StreamableHTTPTransport extends BaseHTTPTra
|
|
|
2121
2138
|
super(opts, "StreamableHTTP");
|
|
2122
2139
|
}
|
|
2123
2140
|
genId() {
|
|
2124
|
-
|
|
2141
|
+
const id = this._nextId;
|
|
2142
|
+
this._nextId = nextJsonRpcId(id);
|
|
2143
|
+
return id;
|
|
2125
2144
|
}
|
|
2126
2145
|
consumeResponseText(text, requestId) {
|
|
2127
2146
|
const envelopes = extractJsonRpcEnvelopes(text);
|
|
@@ -2166,6 +2185,7 @@ var StreamableHTTPTransport = class _StreamableHTTPTransport extends BaseHTTPTra
|
|
|
2166
2185
|
const signal = this.abortController.signal;
|
|
2167
2186
|
const startupTimer = setTimeout(() => this.abortController?.abort(), this.timeout);
|
|
2168
2187
|
try {
|
|
2188
|
+
const initializeId = this.genId();
|
|
2169
2189
|
const initFetchOpts = {
|
|
2170
2190
|
method: "POST",
|
|
2171
2191
|
headers: {
|
|
@@ -2175,7 +2195,7 @@ var StreamableHTTPTransport = class _StreamableHTTPTransport extends BaseHTTPTra
|
|
|
2175
2195
|
},
|
|
2176
2196
|
body: JSON.stringify({
|
|
2177
2197
|
jsonrpc: "2.0",
|
|
2178
|
-
id:
|
|
2198
|
+
id: initializeId,
|
|
2179
2199
|
method: "initialize",
|
|
2180
2200
|
params: {
|
|
2181
2201
|
protocolVersion: MCP_CONSTANTS.PROTOCOL_VERSION,
|
|
@@ -2201,7 +2221,7 @@ var StreamableHTTPTransport = class _StreamableHTTPTransport extends BaseHTTPTra
|
|
|
2201
2221
|
if (!data) {
|
|
2202
2222
|
throw new Error("Could not parse initialize response");
|
|
2203
2223
|
}
|
|
2204
|
-
data = assertMatchingJsonRpcResult(data,
|
|
2224
|
+
data = assertMatchingJsonRpcResult(data, initializeId, "initialize");
|
|
2205
2225
|
if (data.error) {
|
|
2206
2226
|
throw new Error(`initialize failed: ${data.error.message}`);
|
|
2207
2227
|
}
|
|
@@ -2451,6 +2471,7 @@ var MCPClient = class _MCPClient {
|
|
|
2451
2471
|
this.disconnectListeners.delete(listener);
|
|
2452
2472
|
}
|
|
2453
2473
|
async connect() {
|
|
2474
|
+
if (this.state === "connected" || this.state === "connecting") return;
|
|
2454
2475
|
this.state = "connecting";
|
|
2455
2476
|
this._serverMetadata = void 0;
|
|
2456
2477
|
try {
|
|
@@ -2794,7 +2815,7 @@ var MCPClient = class _MCPClient {
|
|
|
2794
2815
|
gracefulTimer.unref?.();
|
|
2795
2816
|
})
|
|
2796
2817
|
]);
|
|
2797
|
-
|
|
2818
|
+
clearTimeout(gracefulTimer);
|
|
2798
2819
|
if (gracefulRace === "timeout") {
|
|
2799
2820
|
forceKillTree(child);
|
|
2800
2821
|
let forceTimer;
|
|
@@ -2805,7 +2826,7 @@ var MCPClient = class _MCPClient {
|
|
|
2805
2826
|
forceTimer.unref?.();
|
|
2806
2827
|
})
|
|
2807
2828
|
]);
|
|
2808
|
-
|
|
2829
|
+
clearTimeout(forceTimer);
|
|
2809
2830
|
}
|
|
2810
2831
|
child.stdout?.removeAllListeners();
|
|
2811
2832
|
child.stderr?.removeAllListeners();
|
|
@@ -2826,7 +2847,8 @@ var MCPClient = class _MCPClient {
|
|
|
2826
2847
|
err.name = "AbortError";
|
|
2827
2848
|
return Promise.reject(err);
|
|
2828
2849
|
}
|
|
2829
|
-
const id = this.nextId
|
|
2850
|
+
const id = this.nextId;
|
|
2851
|
+
this.nextId = nextJsonRpcId(id);
|
|
2830
2852
|
const req = { jsonrpc: "2.0", id, method, params };
|
|
2831
2853
|
return new Promise((resolve, reject) => {
|
|
2832
2854
|
const onAbort = signal ? () => {
|
|
@@ -5015,7 +5037,9 @@ var MCPServer = class {
|
|
|
5015
5037
|
switch (method) {
|
|
5016
5038
|
case "initialize":
|
|
5017
5039
|
return {
|
|
5018
|
-
protocolVersion:
|
|
5040
|
+
protocolVersion: negotiateProtocolVersion(
|
|
5041
|
+
params?.protocolVersion
|
|
5042
|
+
),
|
|
5019
5043
|
capabilities: {
|
|
5020
5044
|
tools: { listChanged: false },
|
|
5021
5045
|
...this.resources.length > 0 ? { resources: { subscribe: false, listChanged: false } } : {},
|
|
@@ -5420,11 +5444,9 @@ async function handleHttpRequest(server, req, res, token, log, boundHost) {
|
|
|
5420
5444
|
req.on("end", () => {
|
|
5421
5445
|
if (aborted) return;
|
|
5422
5446
|
void server.handleMessage(body).then((out) => {
|
|
5423
|
-
if (aborted) return;
|
|
5424
5447
|
if (out === null) return send(202, "");
|
|
5425
5448
|
return send(200, out);
|
|
5426
5449
|
}).catch((err) => {
|
|
5427
|
-
if (aborted) return;
|
|
5428
5450
|
log?.warn?.(`MCP http handler error: ${toErrorMessage2(err)}`);
|
|
5429
5451
|
send(500, JSON.stringify({ error: "internal error" }));
|
|
5430
5452
|
});
|
|
@@ -5795,6 +5817,7 @@ export {
|
|
|
5795
5817
|
MCP_OPERATION_LIMITS,
|
|
5796
5818
|
SSEReader,
|
|
5797
5819
|
SSETransport,
|
|
5820
|
+
SUPPORTED_PROTOCOL_VERSIONS,
|
|
5798
5821
|
StreamableHTTPTransport,
|
|
5799
5822
|
addMcp,
|
|
5800
5823
|
authorizationHeaderForToken,
|
|
@@ -5809,6 +5832,7 @@ export {
|
|
|
5809
5832
|
exchangeMcpAuthorizationCode,
|
|
5810
5833
|
listMcp,
|
|
5811
5834
|
manifestConfigHash,
|
|
5835
|
+
negotiateProtocolVersion,
|
|
5812
5836
|
parseAuthorizationServerMetadata,
|
|
5813
5837
|
parseGetPromptResult,
|
|
5814
5838
|
parseListPromptsResult,
|
package/dist/server.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type IncomingMessage, type ServerResponse } from 'node:http';
|
|
1
2
|
import type { MCPPromptArgument, MCPPromptMessage, MCPResourceContents } from './protocol.js';
|
|
2
3
|
/**
|
|
3
4
|
* Server-side MCP. The mirror image of `MCPClient`: instead of consuming a
|
|
@@ -164,4 +165,5 @@ export interface ServeHttpHandle {
|
|
|
164
165
|
* otherwise expose tool execution to the whole network unauthenticated.
|
|
165
166
|
*/
|
|
166
167
|
export declare function serveHttp(server: MCPServer, opts?: ServeHttpOptions): Promise<ServeHttpHandle>;
|
|
168
|
+
export declare function handleHttpRequest(server: MCPServer, req: IncomingMessage, res: ServerResponse, token: string | undefined, log: MCPServerLogger | undefined, boundHost: string): Promise<void>;
|
|
167
169
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/transport-base.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export interface HttpTransportOptions {
|
|
|
49
49
|
* classifyToolError maps it to FATAL / not-retryable (user cancellation).
|
|
50
50
|
*/
|
|
51
51
|
export declare function makeAbortError(method: string): Error;
|
|
52
|
+
/** Advance a JSON-RPC number id without leaving JavaScript's safe-integer range. */
|
|
53
|
+
export declare function nextJsonRpcId(id: number): number;
|
|
52
54
|
export declare function createTimeoutSignal(parent: AbortSignal | undefined, timeoutMs: number): {
|
|
53
55
|
signal: AbortSignal;
|
|
54
56
|
dispose: () => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack Model Context Protocol client and registry: stdio, SSE, and streamable HTTP transports.",
|
|
6
6
|
"repository": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"!dist/**/*.map"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@wrongstack/core": "1.0.
|
|
29
|
+
"@wrongstack/core": "1.0.4",
|
|
30
30
|
"undici": "^8.10.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|