@wrongstack/mcp 0.284.1 → 0.286.0

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.
@@ -0,0 +1,134 @@
1
+ import type { MCPPromptArgument, MCPPromptMessage, MCPResourceContents } from './protocol.js';
2
+ /**
3
+ * Server-side MCP. The mirror image of `MCPClient`: instead of consuming a
4
+ * remote MCP server, this lets WrongStack *be* an MCP server — exposing its
5
+ * tools to any MCP client (Claude Desktop, another agent, an IDE) over a
6
+ * JSON-RPC 2.0 stream.
7
+ *
8
+ * The protocol core (`MCPServer`) is transport-agnostic: feed it a raw JSON
9
+ * line via `handleMessage`, get back a response string (or `null` for
10
+ * notifications). `serveStdio` wires it to stdin/stdout for the canonical
11
+ * stdio transport.
12
+ */
13
+ /** A tool descriptor advertised over `tools/list`. */
14
+ export interface MCPServerTool {
15
+ name: string;
16
+ description?: string | undefined;
17
+ inputSchema: Record<string, unknown>;
18
+ }
19
+ /** The result of a `tools/call`, as the host produces it. */
20
+ export interface MCPServerCallResult {
21
+ /** Text or pre-built MCP content blocks. Strings are wrapped as a text block. */
22
+ content: unknown;
23
+ isError: boolean;
24
+ }
25
+ /**
26
+ * Bridges the MCP server to a tool backend (in the CLI, the `ToolRegistry`).
27
+ * Kept narrow so the protocol core has no dependency on `@wrongstack/core`.
28
+ */
29
+ export interface MCPServerToolHost {
30
+ listTools(): MCPServerTool[] | Promise<MCPServerTool[]>;
31
+ callTool(name: string, args: Record<string, unknown>): Promise<MCPServerCallResult>;
32
+ }
33
+ export interface MCPServerResource {
34
+ uri: string;
35
+ name: string;
36
+ title?: string | undefined;
37
+ description?: string | undefined;
38
+ mimeType?: string | undefined;
39
+ size?: number | undefined;
40
+ contents: MCPResourceContents[];
41
+ }
42
+ export interface MCPServerPrompt {
43
+ name: string;
44
+ title?: string | undefined;
45
+ description?: string | undefined;
46
+ arguments?: MCPPromptArgument[] | undefined;
47
+ /** Static rich messages, or a text template using {{argument}} placeholders. */
48
+ messages?: MCPPromptMessage[] | undefined;
49
+ template?: string | undefined;
50
+ }
51
+ export interface MCPServerLogger {
52
+ warn?(msg: string): void;
53
+ info?(msg: string): void;
54
+ }
55
+ export interface MCPServerOptions {
56
+ host: MCPServerToolHost;
57
+ /** Advertised in the `initialize` handshake. Defaults to the wrongstack identity. */
58
+ serverInfo?: {
59
+ name: string;
60
+ version: string;
61
+ };
62
+ logger?: MCPServerLogger | undefined;
63
+ /** Explicit allowlist only; omitted means this server exposes no resources. */
64
+ resources?: MCPServerResource[] | undefined;
65
+ /** Explicit allowlist only; omitted means this server exposes no prompts. */
66
+ prompts?: MCPServerPrompt[] | undefined;
67
+ }
68
+ export declare class MCPServer {
69
+ private readonly host;
70
+ private readonly serverInfo;
71
+ private readonly logger?;
72
+ private readonly resources;
73
+ private readonly prompts;
74
+ constructor(opts: MCPServerOptions);
75
+ /**
76
+ * Handle one raw JSON-RPC line. Returns the response JSON string for
77
+ * requests, or `null` for notifications (no `id`) and for blank input —
78
+ * the caller should write the string to its output stream when non-null.
79
+ */
80
+ handleMessage(raw: string): Promise<string | null>;
81
+ private dispatch;
82
+ private encodeError;
83
+ }
84
+ /** Normalize a host result's content into MCP content blocks. */
85
+ export declare function toContentBlocks(content: unknown): Array<{
86
+ type: 'text';
87
+ text: string;
88
+ }>;
89
+ export interface ServeStdioHandle {
90
+ /** Stop reading and detach listeners. Does not exit the process. */
91
+ close(): void;
92
+ /** Resolves when the input stream ends (EOF). */
93
+ done: Promise<void>;
94
+ }
95
+ export interface ServeStdioOptions {
96
+ stdin?: NodeJS.ReadableStream | undefined;
97
+ stdout?: NodeJS.WritableStream | undefined;
98
+ }
99
+ /**
100
+ * Run an `MCPServer` over stdio: newline-delimited JSON-RPC in on stdin,
101
+ * responses out on stdout. CRITICAL: nothing else may write to stdout while
102
+ * this runs — it is the JSON-RPC channel. Route all logging to stderr.
103
+ */
104
+ export declare function serveStdio(server: MCPServer, opts?: ServeStdioOptions): ServeStdioHandle;
105
+ export interface ServeHttpOptions {
106
+ /** TCP port. 0 picks an ephemeral port (resolved in the handle). Default 0. */
107
+ port?: number | undefined;
108
+ /** Bind address. Default '127.0.0.1' (loopback only). */
109
+ host?: string | undefined;
110
+ /**
111
+ * Bearer token required on every request (`Authorization: Bearer <token>`).
112
+ * REQUIRED when binding to a non-loopback host — `serveHttp` refuses to
113
+ * expose tools to the network without one.
114
+ */
115
+ token?: string | undefined;
116
+ logger?: MCPServerLogger | undefined;
117
+ }
118
+ export interface ServeHttpHandle {
119
+ port: number;
120
+ host: string;
121
+ url: string;
122
+ close(): Promise<void>;
123
+ }
124
+ /**
125
+ * Run an `MCPServer` over HTTP: POST a single JSON-RPC request, get the JSON
126
+ * response (notifications → 202 with no body). Reuses `handleMessage`, so the
127
+ * protocol is identical to the stdio transport.
128
+ *
129
+ * Security: binds to loopback by default. Binding to any other host (e.g.
130
+ * `0.0.0.0`) REQUIRES a `token` — otherwise this rejects, because it would
131
+ * otherwise expose tool execution to the whole network unauthenticated.
132
+ */
133
+ export declare function serveHttp(server: MCPServer, opts?: ServeHttpOptions): Promise<ServeHttpHandle>;
134
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { MCPTool } from '../client.js';
2
+ export interface MockToolResponse {
3
+ content: unknown;
4
+ isError?: boolean | undefined;
5
+ }
6
+ export interface MockMCPServerOptions {
7
+ /** Delay injected between receiving a request and sending the response (ms). */
8
+ responseDelayMs?: number | undefined;
9
+ }
10
+ /**
11
+ * Minimal in-process MCP server that speaks JSON-RPC over stdio.
12
+ * Writes a self-contained Node.js script to a temp file and exposes the path
13
+ * for spawning as a child process.
14
+ */
15
+ export declare class MockMCPServer {
16
+ private readonly tools;
17
+ private readonly delayMs;
18
+ /** Responses keyed by `JSON.stringify(params)` for tools/call. */
19
+ private readonly responses;
20
+ private scriptPath?;
21
+ constructor(tools?: MCPTool[], opts?: MockMCPServerOptions);
22
+ setResponse(params: unknown, response: MockToolResponse | string): void;
23
+ setTools(tools: MCPTool[]): void;
24
+ /**
25
+ * Write the mock server script to a temp file and return the path.
26
+ * The script is self-contained and requires no external dependencies.
27
+ */
28
+ writeScript(): Promise<string>;
29
+ /** Delete the temp script. Call after test completes. */
30
+ cleanup(): Promise<void>;
31
+ /** Path to the script if already written via writeScript(). */
32
+ get path(): string | undefined;
33
+ }
34
+ //# sourceMappingURL=mock-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-server.d.ts","sourceRoot":"","sources":["../../src/test-helpers/mock-server.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,kEAAkE;IAClE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IACjE,OAAO,CAAC,UAAU,CAAC,CAAqB;IAExC,YAAY,KAAK,GAAE,OAAO,EAAO,EAAE,IAAI,GAAE,oBAAyB,EAGjE;IAED,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAKtE;IAED,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAG/B;IAED;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAoDnC;IAED,yDAAyD;IACnD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAS7B;IAED,+DAA+D;IAC/D,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;CACF"}
@@ -0,0 +1,56 @@
1
+ import type { MCPServerConfig, SecretVault } from '@wrongstack/core';
2
+ import { type MCPAuthorizationChallenge, type MCPAuthorizationContext, type MCPAuthorizationProvider, type MCPAuthorizationServerMetadata, type MCPTokenSet } from './authorization.js';
3
+ export interface MCPStoredAuthorization {
4
+ serverName: string;
5
+ resource: string;
6
+ clientId: string;
7
+ authorizationServer: MCPAuthorizationServerMetadata;
8
+ tokenSet: MCPTokenSet;
9
+ updatedAt: string;
10
+ }
11
+ export interface MCPAuthorizationStateEvent {
12
+ serverName: string;
13
+ state: 'authorized' | 'refreshed' | 'reauth_required' | 'removed';
14
+ resource: string;
15
+ expiresAt?: number | undefined;
16
+ scopes?: string[] | undefined;
17
+ }
18
+ export interface MCPRefreshingAuthorizationProviderOptions {
19
+ serverName: string;
20
+ resource: string;
21
+ store: MCPVaultTokenStore;
22
+ refreshSkewMs?: number | undefined;
23
+ onStateChange?: ((event: MCPAuthorizationStateEvent) => void) | undefined;
24
+ }
25
+ export interface MCPVaultProviderFactoryOptions {
26
+ store: MCPVaultTokenStore;
27
+ refreshSkewMs?: number | undefined;
28
+ onStateChange?: ((event: MCPAuthorizationStateEvent) => void) | undefined;
29
+ }
30
+ export declare class MCPVaultTokenStore {
31
+ private readonly filePath;
32
+ private readonly vault;
33
+ constructor(filePath: string, vault: SecretVault);
34
+ load(serverName: string, resource: string): Promise<MCPStoredAuthorization | undefined>;
35
+ save(value: MCPStoredAuthorization): Promise<void>;
36
+ remove(serverName: string, resource: string): Promise<boolean>;
37
+ private readFile;
38
+ private writeFile;
39
+ private encryptEntry;
40
+ private decryptEntry;
41
+ }
42
+ export declare class MCPRefreshingAuthorizationProvider implements MCPAuthorizationProvider {
43
+ private readonly options;
44
+ private refreshPromise?;
45
+ private readonly resource;
46
+ private readonly refreshSkewMs;
47
+ constructor(options: MCPRefreshingAuthorizationProviderOptions);
48
+ getAccessToken(context: MCPAuthorizationContext): Promise<MCPTokenSet | undefined>;
49
+ handleUnauthorized(challenge: MCPAuthorizationChallenge, context: MCPAuthorizationContext): Promise<boolean>;
50
+ private refresh;
51
+ private refreshInner;
52
+ private assertContext;
53
+ private emit;
54
+ }
55
+ export declare function createVaultBackedMcpAuthorizationProviderFactory(options: MCPVaultProviderFactoryOptions): (server: Readonly<MCPServerConfig>) => MCPAuthorizationProvider | undefined;
56
+ //# sourceMappingURL=token-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../src/token-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAErE,OAAO,EAGL,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EACnC,KAAK,WAAW,EAGjB,MAAM,oBAAoB,CAAC;AAO5B,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,8BAA8B,CAAC;IACpD,QAAQ,EAAE,WAAW,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAqBD,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,YAAY,GAAG,WAAW,GAAG,iBAAiB,GAAG,SAAS,CAAC;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,yCAAyC;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,aAAa,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC3E;AAED,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,kBAAkB,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,aAAa,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC3E;AAED,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFxB,YACmB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,WAAW,EACjC;IAEE,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC,CAU5F;IAEK,IAAI,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAavD;IAEK,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWnE;YAEa,QAAQ;YAmBR,SAAS;IASvB,OAAO,CAAC,YAAY;IAyBpB,OAAO,CAAC,YAAY;CAwBrB;AAED,qBAAa,kCAAmC,YAAW,wBAAwB;IAKrE,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,cAAc,CAAC,CAA0D;IACjF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAEvC,YAA6B,OAAO,EAAE,yCAAyC,EAG9E;IAEK,cAAc,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAiBvF;IAEK,kBAAkB,CACtB,SAAS,EAAE,yBAAyB,EACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,OAAO,CAAC,CASlB;IAED,OAAO,CAAC,OAAO;YAWD,YAAY;IA0B1B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,IAAI;CASb;AAED,wBAAgB,gDAAgD,CAC9D,OAAO,EAAE,8BAA8B,GACtC,CAAC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,KAAK,wBAAwB,GAAG,SAAS,CAmB7E"}
@@ -0,0 +1,3 @@
1
+ import type { MCPTool } from './client.js';
2
+ export declare function normalizeMCPTools(value: unknown): MCPTool[];
3
+ //# sourceMappingURL=tool-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-schema.d.ts","sourceRoot":"","sources":["../src/tool-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,CA8B3D"}
@@ -0,0 +1,161 @@
1
+ import * as https from 'node:https';
2
+ import { type MCPAuthorizationProvider } from './authorization.js';
3
+ import type { ConnectionState, JsonRpcResponse, MCPTool, ToolCallResult } from './client.js';
4
+ import { type MCPServerMetadata } from './protocol.js';
5
+ export type JsonRpcResult = {
6
+ jsonrpc: string;
7
+ id?: number | undefined;
8
+ result?: unknown | undefined;
9
+ error?: {
10
+ code: number | undefined;
11
+ message: string;
12
+ data?: unknown | undefined;
13
+ } | undefined;
14
+ };
15
+ export interface HttpTransportOptions {
16
+ name: string;
17
+ url: string;
18
+ headers?: Record<string, string> | undefined;
19
+ startupTimeoutMs?: number | undefined;
20
+ requestTimeoutMs?: number | undefined;
21
+ authorizationProvider?: MCPAuthorizationProvider | undefined;
22
+ /**
23
+ * Per-request TLS configuration. When set, an https.Agent is created
24
+ * and passed to fetch via the `dispatch` option. This avoids globally
25
+ * disabling certificate validation (NODE_TLS_REJECT_UNAUTHORIZED) which
26
+ * would affect all provider API calls in the same process.
27
+ *
28
+ * ⚠️ Security gate: `rejectUnauthorized: false` REQUIRES
29
+ * `WRONGSTACK_UNSAFE_MCP_TLS=1` as an explicit opt-in.
30
+ *
31
+ * Without this gate, an active network attacker between the client and the
32
+ * MCP server can read and modify tool calls and responses. Only use this
33
+ * for local development with self-signed certificates; production MCP
34
+ * servers must present a valid certificate.
35
+ */
36
+ tls?: {
37
+ ca?: string | undefined;
38
+ rejectUnauthorized?: boolean | undefined;
39
+ };
40
+ }
41
+ export declare class SSEReader {
42
+ private buffer;
43
+ private dataLines;
44
+ private listeners;
45
+ onMessage(cb: (data: {
46
+ jsonrpc?: string | undefined;
47
+ method?: string | undefined;
48
+ params?: unknown | undefined;
49
+ id?: number | undefined;
50
+ }) => void): () => void;
51
+ feed(chunk: string): void;
52
+ private processLine;
53
+ private flush;
54
+ private dispatch;
55
+ reset(): void;
56
+ }
57
+ /** Extract only response envelopes; notifications and server requests are not responses. */
58
+ export declare function extractJsonRpcResults(text: string): JsonRpcResult[];
59
+ /**
60
+ * Fields and methods shared by all HTTP-based MCP transports.
61
+ * Subclasses override `connect()`, `close()`, `callTool()`, `request()`.
62
+ */
63
+ export declare abstract class BaseHTTPTransport {
64
+ protected state: ConnectionState;
65
+ protected readonly url: string;
66
+ protected readonly headers: Record<string, string>;
67
+ protected readonly timeout: number;
68
+ protected readonly requestTimeout: number;
69
+ protected readonly name: string;
70
+ protected readonly authorizationProvider?: MCPAuthorizationProvider | undefined;
71
+ protected readonly authorizationResource: string;
72
+ /** Per-request TLS agent — created once from HttpTransportOptions.tls */
73
+ protected readonly tlsAgent?: https.Agent | undefined;
74
+ protected readonly tools: MCPTool[];
75
+ protected serverMetadata?: MCPServerMetadata | undefined;
76
+ protected abortController?: AbortController | undefined;
77
+ protected readonly disconnectHandlers: Array<() => void>;
78
+ protected readonly toolsChangedListeners: Set<(tools: MCPTool[]) => void>;
79
+ protected readonly resourcesChangedListeners: Set<() => void>;
80
+ protected readonly promptsChangedListeners: Set<() => void>;
81
+ protected protocolVersion?: string | undefined;
82
+ constructor(opts: HttpTransportOptions, transportName: string);
83
+ getState(): ConnectionState;
84
+ protected fetchWithAuthorization(input: string, init: RequestInit, signal?: AbortSignal | undefined): Promise<Response>;
85
+ listTools(): MCPTool[];
86
+ getServerMetadata(): MCPServerMetadata | undefined;
87
+ onDisconnect(cb: () => void): () => void;
88
+ onToolsChanged(cb: (tools: MCPTool[]) => void): () => void;
89
+ onResourcesChanged(cb: () => void): () => void;
90
+ onPromptsChanged(cb: () => void): () => void;
91
+ /**
92
+ * Fire all disconnect handlers. Subclasses call this when the connection
93
+ * drops so the registry can schedule reconnects.
94
+ */
95
+ protected notifyDisconnect(): void;
96
+ protected notifyResourcesChanged(): void;
97
+ protected notifyPromptsChanged(): void;
98
+ /**
99
+ * Apply the pinned TLS agent (if configured) to a `RequestInit` object.
100
+ * Uses `HttpDispatcher` from `@wrongstack/core`'s dispatcher-types shim,
101
+ * which declares `https.Agent` compatible with `RequestInit.dispatcher`.
102
+ * Verified safe: https.Agent implements the `dispatch(req, opts)` method
103
+ * that fetch requires at runtime.
104
+ */
105
+ protected applyTlsAgent(fetchOpts: RequestInit): void;
106
+ /** Generate the next JSON-RPC request id. Subclasses provide the counter. */
107
+ protected abstract genId(): number;
108
+ }
109
+ /**
110
+ * SSE transport for MCP over HTTP.
111
+ *
112
+ * Uses native fetch API with ReadableStream to consume SSE events.
113
+ * HTTP POST is used to send JSON-RPC requests.
114
+ */
115
+ export declare class SSETransport extends BaseHTTPTransport {
116
+ private _nextId;
117
+ private readerDone;
118
+ private readLoopAbort?;
119
+ private reader?;
120
+ constructor(opts: HttpTransportOptions);
121
+ protected genId(): number;
122
+ /** Refresh tool list when server sends notifications/tools/list_changed. */
123
+ private handleToolsListChanged;
124
+ connect(): Promise<void>;
125
+ private readSSEBody;
126
+ private buildSSEUrl;
127
+ private httpPost;
128
+ callTool(name: string, input: unknown, opts?: {
129
+ signal?: AbortSignal | undefined;
130
+ }): Promise<ToolCallResult>;
131
+ /** Generic JSON-RPC request — used by MCPClient.request() for SSE transports. */
132
+ request(method: string, params: unknown, timeoutMs?: number, opts?: {
133
+ signal?: AbortSignal | undefined;
134
+ }): Promise<JsonRpcResponse>;
135
+ close(): Promise<void>;
136
+ }
137
+ /**
138
+ * Streamable HTTP transport for MCP.
139
+ *
140
+ * Uses session-based HTTP with NDJSON responses.
141
+ */
142
+ export declare class StreamableHTTPTransport extends BaseHTTPTransport {
143
+ private _nextId;
144
+ private sessionId?;
145
+ constructor(opts: HttpTransportOptions);
146
+ protected genId(): number;
147
+ private consumeResponseText;
148
+ private handleNotification;
149
+ private refreshTools;
150
+ connect(): Promise<void>;
151
+ private postRaw;
152
+ /** Generic JSON-RPC request — used by MCPClient.request() for SSE/streamable-http transports. */
153
+ request(method: string, params: unknown, timeoutMs?: number, opts?: {
154
+ signal?: AbortSignal | undefined;
155
+ }): Promise<JsonRpcResponse>;
156
+ callTool(name: string, input: unknown, opts?: {
157
+ signal?: AbortSignal | undefined;
158
+ }): Promise<ToolCallResult>;
159
+ close(): Promise<void>;
160
+ }
161
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type Permission, type Tool } from '@wrongstack/core';
2
+ import type { MCPClient, MCPTool } from './client.js';
3
+ /**
4
+ * Resolves the live client for a tool call. A plain {@link MCPClient} for eager
5
+ * servers, or a thunk that connects-on-demand for lazy/dormant servers (the
6
+ * registry passes `() => this.ensureConnected(name)`).
7
+ */
8
+ export type MCPClientResolver = MCPClient | (() => Promise<MCPClient>);
9
+ export interface MCPToolCallObserver {
10
+ onStart(): void;
11
+ onFinish(result: {
12
+ durationMs: number;
13
+ ok: boolean;
14
+ }): void;
15
+ }
16
+ export declare function wrapMCPTool(serverName: string, mcpTool: MCPTool, client: MCPClientResolver, permission?: Permission, observer?: MCPToolCallObserver | undefined): Tool;
17
+ //# sourceMappingURL=wrap-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap-tool.d.ts","sourceRoot":"","sources":["../src/wrap-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAoB,MAAM,kBAAkB,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAwBtD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;AAEvE,MAAM,WAAW,mBAAmB;IAClC,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CAC7D;AAED,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,iBAAiB,EACzB,UAAU,GAAE,UAAsB,EAClC,QAAQ,CAAC,EAAE,mBAAmB,GAAG,SAAS,GACzC,IAAI,CAgCN"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/mcp",
3
- "version": "0.284.1",
3
+ "version": "0.286.0",
4
4
  "license": "MIT",
5
5
  "description": "WrongStack Model Context Protocol client and registry: stdio, SSE, and streamable HTTP transports.",
6
6
  "repository": {
@@ -25,12 +25,11 @@
25
25
  "dist"
26
26
  ],
27
27
  "dependencies": {
28
- "@wrongstack/core": "0.284.1"
28
+ "@wrongstack/core": "0.286.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/node": "^26.0.1",
32
- "tsup": "^8.5.1",
33
- "typescript": "^6.0.3",
32
+ "typescript": "^7.0.2",
34
33
  "undici": "^8.5.0",
35
34
  "undici-types": "^8.5.0",
36
35
  "vitest": "^4.1.9"
@@ -39,7 +38,7 @@
39
38
  "access": "public"
40
39
  },
41
40
  "scripts": {
42
- "build": "tsup",
41
+ "build": "node ../../scripts/build-package.mjs",
43
42
  "typecheck": "tsc --noEmit -p tsconfig.test.json",
44
43
  "test": "vitest run",
45
44
  "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\""