@wrongstack/mcp 1.0.24 → 1.0.27
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/authorization-callback-server.d.ts +24 -0
- package/dist/authorization-discovery.d.ts +96 -0
- package/dist/authorization-manager.d.ts +46 -1
- package/dist/authorization-registration.d.ts +39 -0
- package/dist/authorization.d.ts +6 -61
- package/dist/client-http-connection.d.ts +22 -0
- package/dist/client-types.d.ts +8 -0
- package/dist/client.d.ts +24 -3
- package/dist/config-env.d.ts +18 -0
- package/dist/constants.d.ts +26 -5
- package/dist/contracts.d.ts +21 -0
- package/dist/elicitation-form.d.ts +26 -0
- package/dist/elicitation.d.ts +151 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +1988 -656
- package/dist/manage.d.ts +4 -0
- package/dist/protocol.d.ts +10 -0
- package/dist/registry-authorization.d.ts +3 -2
- package/dist/registry-connect-loop.d.ts +1 -0
- package/dist/registry-slots.d.ts +6 -0
- package/dist/registry-types.d.ts +6 -0
- package/dist/registry.d.ts +12 -1
- package/dist/structured-result.d.ts +7 -0
- package/dist/token-store.d.ts +5 -1
- package/dist/tool-schema.d.ts +14 -1
- package/dist/transport-base.d.ts +26 -4
- package/dist/transport-streamable.d.ts +14 -1
- package/dist/wrap-tool.d.ts +4 -2
- package/package.json +2 -2
package/dist/manage.d.ts
CHANGED
|
@@ -17,6 +17,10 @@ export interface McpServerInput {
|
|
|
17
17
|
bearerTokenEnv?: string | undefined;
|
|
18
18
|
allowedTools?: string[] | undefined;
|
|
19
19
|
permission?: Permission | undefined;
|
|
20
|
+
/** Connect/startup timeout in ms. Defaults to 10s when omitted. */
|
|
21
|
+
startupTimeoutMs?: number | undefined;
|
|
22
|
+
/** Per-request JSON-RPC timeout in ms. Defaults to 60s when omitted. */
|
|
23
|
+
requestTimeoutMs?: number | undefined;
|
|
20
24
|
/** Lazy connect — spawn the process only on first tool call (see config). */
|
|
21
25
|
lazy?: boolean | undefined;
|
|
22
26
|
/** Env var names to forward from parent process at spawn time. */
|
package/dist/protocol.d.ts
CHANGED
|
@@ -88,4 +88,14 @@ export declare function parseListResourceTemplatesResult(value: unknown): MCPLis
|
|
|
88
88
|
export declare function parseReadResourceResult(value: unknown): MCPReadResourceResult;
|
|
89
89
|
export declare function parseListPromptsResult(value: unknown): MCPListPromptsResult;
|
|
90
90
|
export declare function parseGetPromptResult(value: unknown): MCPGetPromptResult;
|
|
91
|
+
/**
|
|
92
|
+
* Extract the `uri` from a `notifications/resources/updated` payload.
|
|
93
|
+
*
|
|
94
|
+
* The notification is the whole point of `resources/subscribe`, which the
|
|
95
|
+
* client already supported — every transport parsed the three `list_changed`
|
|
96
|
+
* notifications and silently dropped this one, so a subscription produced
|
|
97
|
+
* nothing. Returns `undefined` for a malformed payload rather than throwing:
|
|
98
|
+
* a notification has no reply, so a bad one is ignored, not answered.
|
|
99
|
+
*/
|
|
100
|
+
export declare function resourceUpdatedUri(params: unknown): string | undefined;
|
|
91
101
|
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { MCPServerConfig } from '@wrongstack/core/types';
|
|
2
|
-
import type { MCPAuthorizationManager, MCPAuthorizationStartResult, MCPAuthorizationStatus } from './authorization-manager.js';
|
|
2
|
+
import type { MCPAuthorizationLoginHandle, MCPAuthorizationLoginInput, MCPAuthorizationManager, MCPAuthorizationStartResult, MCPAuthorizationStatus } from './authorization-manager.js';
|
|
3
3
|
import type { ServerSlot } from './registry-slots.js';
|
|
4
4
|
export declare function requireAuthorizationManager(manager: MCPAuthorizationManager | undefined): MCPAuthorizationManager;
|
|
5
5
|
export declare function requireHttpServerConfig(servers: Map<string, ServerSlot>, disabledServers: Map<string, MCPServerConfig>, name: string): MCPServerConfig;
|
|
6
|
+
export declare function loginRegistryAuthorization(manager: MCPAuthorizationManager | undefined, cfg: MCPServerConfig, name: string, input: Omit<MCPAuthorizationLoginInput, 'serverName' | 'resource'>): Promise<MCPAuthorizationLoginHandle>;
|
|
6
7
|
export declare function beginRegistryAuthorization(manager: MCPAuthorizationManager | undefined, cfg: MCPServerConfig, name: string, input: {
|
|
7
|
-
clientId
|
|
8
|
+
clientId?: string | undefined;
|
|
8
9
|
redirectUri: string;
|
|
9
10
|
scopes?: readonly string[] | undefined;
|
|
10
11
|
challengeHeader?: string | null | undefined;
|
|
@@ -15,6 +15,7 @@ export interface RegistryConnectContext {
|
|
|
15
15
|
cacheDir?: string | undefined;
|
|
16
16
|
cwd?: string | undefined;
|
|
17
17
|
authorizationProviderFactory?: MCPRegistryOptions['authorizationProviderFactory'] | undefined;
|
|
18
|
+
elicitationHandler?: MCPRegistryOptions['elicitationHandler'] | undefined;
|
|
18
19
|
operationListeners: Set<MCPOperationListener>;
|
|
19
20
|
ensureConnected: (name: string) => Promise<MCPClient>;
|
|
20
21
|
recordOperation: (slot: ServerSlot, kind: MCPOperationKind, reason?: string, failureKind?: MCPFailureKind, durationMs?: number, retain?: boolean) => void;
|
package/dist/registry-slots.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { MCPServerConfig, Tool } from '@wrongstack/core/types';
|
|
2
2
|
import type { MCPClient } from './client.js';
|
|
3
3
|
import type { ConnectionState, MCPTool } from './contracts.js';
|
|
4
|
+
import type { ElicitationRequester } from './elicitation.js';
|
|
4
5
|
import type { MCPServerOperationState } from './operations.js';
|
|
5
6
|
import type { MCPPrompt, MCPResource, MCPResourceTemplate, MCPServerMetadata } from './protocol.js';
|
|
6
7
|
export interface ServerSlot {
|
|
@@ -40,6 +41,11 @@ export interface ServerSlot {
|
|
|
40
41
|
connecting?: Promise<MCPClient | undefined> | undefined;
|
|
41
42
|
/** Whether this lazy server's resolver wrappers are registered (register once). */
|
|
42
43
|
registeredLazy: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Runs with a tool call to this server in flight, oldest first. A server
|
|
46
|
+
* elicitation asks the newest — the spec does not tie a request to a call.
|
|
47
|
+
*/
|
|
48
|
+
activeCallers?: ElicitationRequester[] | undefined;
|
|
43
49
|
/** Bounded, payload-free operational telemetry for this server. */
|
|
44
50
|
operations: MCPServerOperationState;
|
|
45
51
|
}
|
package/dist/registry-types.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { Logger, MCPServerConfig } from '@wrongstack/core/types';
|
|
|
4
4
|
import type { MCPAuthorizationProvider } from './authorization.js';
|
|
5
5
|
import type { MCPAuthorizationManager } from './authorization-manager.js';
|
|
6
6
|
import type { ConnectionState } from './contracts.js';
|
|
7
|
+
import type { MCPElicitationHandler } from './elicitation.js';
|
|
7
8
|
import type { MCPPrompt, MCPResource, MCPResourceTemplate, MCPServerMetadata } from './protocol.js';
|
|
8
9
|
export interface MCPRegistryOptions {
|
|
9
10
|
toolRegistry: ToolRegistry;
|
|
@@ -20,6 +21,11 @@ export interface MCPRegistryOptions {
|
|
|
20
21
|
lazyMode?: boolean | undefined;
|
|
21
22
|
authorizationProviderFactory?: ((server: Readonly<MCPServerConfig>) => MCPAuthorizationProvider | undefined) | undefined;
|
|
22
23
|
authorizationManager?: MCPAuthorizationManager | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Puts a server's `elicitation/create` form in front of the user. Without
|
|
26
|
+
* it the capability is not declared, so servers never send the request.
|
|
27
|
+
*/
|
|
28
|
+
elicitationHandler?: MCPElicitationHandler | undefined;
|
|
23
29
|
}
|
|
24
30
|
export interface MCPRegistryCatalog {
|
|
25
31
|
name: string;
|
package/dist/registry.d.ts
CHANGED
|
@@ -20,13 +20,17 @@ export declare class MCPRegistry {
|
|
|
20
20
|
private readonly idleTimeoutMs;
|
|
21
21
|
private readonly authorizationProviderFactory?;
|
|
22
22
|
private readonly authorizationManager?;
|
|
23
|
+
private readonly elicitationHandler?;
|
|
23
24
|
private readonly operationListeners;
|
|
25
|
+
/** Starts still in flight, for {@link whenStarted}. */
|
|
26
|
+
private readonly startups;
|
|
24
27
|
/** Single shared idle sweep timer (started lazily; unref'd; cleared on stopAll). */
|
|
25
28
|
private idleTimer?;
|
|
26
29
|
constructor(opts: MCPRegistryOptions);
|
|
27
30
|
private requireSlot;
|
|
31
|
+
loginAuthorization(name: string, input: Omit<import('./authorization-manager.js').MCPAuthorizationLoginInput, 'serverName' | 'resource'>): Promise<import('./authorization-manager.js').MCPAuthorizationLoginHandle>;
|
|
28
32
|
beginAuthorization(name: string, input: {
|
|
29
|
-
clientId
|
|
33
|
+
clientId?: string | undefined;
|
|
30
34
|
redirectUri: string;
|
|
31
35
|
scopes?: readonly string[] | undefined;
|
|
32
36
|
challengeHeader?: string | null | undefined;
|
|
@@ -37,6 +41,12 @@ export declare class MCPRegistry {
|
|
|
37
41
|
disconnectAuthorization(name: string): Promise<boolean>;
|
|
38
42
|
private requireHttpServerConfig;
|
|
39
43
|
start(cfg: MCPServerConfig): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Resolves once every start already in flight has connected or failed. A
|
|
46
|
+
* host that starts its servers in the background and then runs a single
|
|
47
|
+
* turn waits here, so the turn's tool list includes theirs.
|
|
48
|
+
*/
|
|
49
|
+
whenStarted(): Promise<void>;
|
|
40
50
|
/** Record an intentionally disabled configuration without opening a transport. */
|
|
41
51
|
markDisabled(cfg: MCPServerConfig): void;
|
|
42
52
|
/** Remove residual operational/configuration state after a management delete. */
|
|
@@ -175,6 +185,7 @@ export declare class MCPRegistry {
|
|
|
175
185
|
*/
|
|
176
186
|
private readonly onToolsChanged;
|
|
177
187
|
private readonly onResourcesChanged;
|
|
188
|
+
private readonly onResourceUpdated;
|
|
178
189
|
private readonly onPromptsChanged;
|
|
179
190
|
private addCatalogListeners;
|
|
180
191
|
private removeCatalogListeners;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model-facing text of a successful call: the rendered content, plus the
|
|
3
|
+
* structured result when the content does not already contain it, plus a
|
|
4
|
+
* notice when the result breaks the tool's own `outputSchema`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function renderStructuredResult(rendered: string, content: unknown, structured: Record<string, unknown> | undefined, outputSchema: Record<string, unknown> | undefined): string;
|
|
7
|
+
//# sourceMappingURL=structured-result.d.ts.map
|
package/dist/token-store.d.ts
CHANGED
|
@@ -4,16 +4,20 @@ export interface MCPStoredAuthorization {
|
|
|
4
4
|
serverName: string;
|
|
5
5
|
resource: string;
|
|
6
6
|
clientId: string;
|
|
7
|
+
/** Present only for a confidential client issued by dynamic registration. */
|
|
8
|
+
clientSecret?: string | undefined;
|
|
7
9
|
authorizationServer: MCPAuthorizationServerMetadata;
|
|
8
10
|
tokenSet: MCPTokenSet;
|
|
9
11
|
updatedAt: string;
|
|
10
12
|
}
|
|
11
13
|
export interface MCPAuthorizationStateEvent {
|
|
12
14
|
serverName: string;
|
|
13
|
-
state: 'authorized' | 'refreshed' | 'reauth_required' | 'removed';
|
|
15
|
+
state: 'authorized' | 'refreshed' | 'reauth_required' | 'removed' | 'failed';
|
|
14
16
|
resource: string;
|
|
15
17
|
expiresAt?: number | undefined;
|
|
16
18
|
scopes?: string[] | undefined;
|
|
19
|
+
/** Non-secret reason, set for `failed`. Never contains a token or code. */
|
|
20
|
+
message?: string | undefined;
|
|
17
21
|
}
|
|
18
22
|
export interface MCPRefreshingAuthorizationProviderOptions {
|
|
19
23
|
serverName: string;
|
package/dist/tool-schema.d.ts
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
import type { MCPTool } from './contracts.js';
|
|
1
|
+
import type { MCPTool, ToolCallResult } from './contracts.js';
|
|
2
|
+
/**
|
|
3
|
+
* The ONE reading of a `tools/call` response, shared by every transport. A
|
|
4
|
+
* JSON-RPC error becomes an error result; `structuredContent` is kept only
|
|
5
|
+
* when it is the object the spec requires.
|
|
6
|
+
*/
|
|
7
|
+
export declare function toToolCallResult(response: {
|
|
8
|
+
result?: unknown | undefined;
|
|
9
|
+
error?: {
|
|
10
|
+
message: string;
|
|
11
|
+
code?: number | undefined;
|
|
12
|
+
data?: unknown;
|
|
13
|
+
} | undefined;
|
|
14
|
+
}): ToolCallResult;
|
|
2
15
|
/**
|
|
3
16
|
* Collect every page of `tools/list`.
|
|
4
17
|
*
|
package/dist/transport-base.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as https from 'node:https';
|
|
2
2
|
import { type MCPAuthorizationProvider } from './authorization.js';
|
|
3
3
|
import type { ConnectionState, MCPTool } from './contracts.js';
|
|
4
|
+
import { type ServerRequest, ServerRequestResponder } from './elicitation.js';
|
|
4
5
|
import type { MCPServerMetadata } from './protocol.js';
|
|
5
6
|
import { type TransportDnsLookup } from './transport-security.js';
|
|
6
7
|
export interface HttpTransportOptions {
|
|
@@ -43,18 +44,21 @@ export interface HttpTransportOptions {
|
|
|
43
44
|
* record is policy-checked before the dial.
|
|
44
45
|
*/
|
|
45
46
|
lookup?: TransportDnsLookup | undefined;
|
|
47
|
+
/** The owning client's answerer for server→client requests (shared across reconnects). */
|
|
48
|
+
serverRequests?: ServerRequestResponder | undefined;
|
|
46
49
|
}
|
|
47
50
|
/**
|
|
48
51
|
* Abort error whose `name` is `'AbortError'` so the core executor's
|
|
49
52
|
* classifyToolError maps it to FATAL / not-retryable (user cancellation).
|
|
50
53
|
*/
|
|
54
|
+
/**
|
|
55
|
+
* `scheme://host:port` of a server URL, for log lines. The path and query can
|
|
56
|
+
* hold an expanded `${SECRET}` (config-env), and userinfo is a credential.
|
|
57
|
+
*/
|
|
58
|
+
export declare function urlOriginForLog(raw: string): string;
|
|
51
59
|
export declare function makeAbortError(method: string): Error;
|
|
52
60
|
/** Advance a JSON-RPC number id without leaving JavaScript's safe-integer range. */
|
|
53
61
|
export declare function nextJsonRpcId(id: number): number;
|
|
54
|
-
export declare function createTimeoutSignal(parent: AbortSignal | undefined, timeoutMs: number): {
|
|
55
|
-
signal: AbortSignal;
|
|
56
|
-
dispose: () => void;
|
|
57
|
-
};
|
|
58
62
|
/**
|
|
59
63
|
* Fields and methods shared by all HTTP-based MCP transports.
|
|
60
64
|
* Subclasses override `connect()`, `close()`, `callTool()`, `request()`.
|
|
@@ -80,8 +84,10 @@ export declare abstract class BaseHTTPTransport {
|
|
|
80
84
|
protected readonly disconnectHandlers: Array<() => void>;
|
|
81
85
|
protected readonly toolsChangedListeners: Set<(tools: MCPTool[]) => void>;
|
|
82
86
|
protected readonly resourcesChangedListeners: Set<() => void>;
|
|
87
|
+
protected readonly resourceUpdatedListeners: Set<(uri: string) => void>;
|
|
83
88
|
protected readonly promptsChangedListeners: Set<() => void>;
|
|
84
89
|
protected protocolVersion?: string | undefined;
|
|
90
|
+
protected readonly serverRequests: ServerRequestResponder;
|
|
85
91
|
constructor(opts: HttpTransportOptions, transportName: string);
|
|
86
92
|
getState(): ConnectionState;
|
|
87
93
|
protected fetchWithAuthorization(input: string | URL, init: RequestInit, signal?: AbortSignal | undefined): Promise<Response>;
|
|
@@ -91,6 +97,7 @@ export declare abstract class BaseHTTPTransport {
|
|
|
91
97
|
onToolsChanged(cb: (tools: MCPTool[]) => void): () => void;
|
|
92
98
|
onResourcesChanged(cb: () => void): () => void;
|
|
93
99
|
onPromptsChanged(cb: () => void): () => void;
|
|
100
|
+
onResourceUpdated(cb: (uri: string) => void): () => void;
|
|
94
101
|
/**
|
|
95
102
|
* Fire all disconnect handlers. Subclasses call this when the connection
|
|
96
103
|
* drops so the registry can schedule reconnects.
|
|
@@ -98,6 +105,7 @@ export declare abstract class BaseHTTPTransport {
|
|
|
98
105
|
protected notifyDisconnect(): void;
|
|
99
106
|
protected notifyResourcesChanged(): void;
|
|
100
107
|
protected notifyPromptsChanged(): void;
|
|
108
|
+
protected notifyResourceUpdated(uri: string): void;
|
|
101
109
|
private dispatcherFetch;
|
|
102
110
|
private pinnedDispatcher;
|
|
103
111
|
private applyPinnedDispatcher;
|
|
@@ -117,6 +125,20 @@ export declare abstract class BaseHTTPTransport {
|
|
|
117
125
|
* these same TLS options plus the resolution-bound lookup.
|
|
118
126
|
*/
|
|
119
127
|
protected applyTlsAgent(fetchOpts: RequestInit): void;
|
|
128
|
+
/**
|
|
129
|
+
* Request timeout for a call. It holds while the server waits on the user's
|
|
130
|
+
* elicitation answer — that wait is the user typing, not the server stalling.
|
|
131
|
+
*/
|
|
132
|
+
protected requestTimeoutSignal(parent: AbortSignal | undefined, timeoutMs: number): {
|
|
133
|
+
signal: AbortSignal;
|
|
134
|
+
dispose: () => void;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Answer a server→client request. Over HTTP the reply is POSTed back like
|
|
138
|
+
* any client message; the server acknowledges it with 202. A failed reply is
|
|
139
|
+
* not retried — the server times its request out on its side.
|
|
140
|
+
*/
|
|
141
|
+
protected replyToServer(request: ServerRequest, url: string, headers: Record<string, string>): Promise<void>;
|
|
120
142
|
/** Generate the next JSON-RPC request id. Subclasses provide the counter. */
|
|
121
143
|
protected abstract genId(): number;
|
|
122
144
|
}
|
|
@@ -11,7 +11,20 @@ export declare class StreamableHTTPTransport extends BaseHTTPTransport {
|
|
|
11
11
|
private sessionId?;
|
|
12
12
|
constructor(opts: HttpTransportOptions);
|
|
13
13
|
protected genId(): number;
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Read a POST's reply. A `text/event-stream` reply is consumed event by
|
|
16
|
+
* event: the server may put notifications and its OWN requests (elicitation)
|
|
17
|
+
* ahead of our response and then wait for our answer to them, so buffering
|
|
18
|
+
* the whole body first would deadlock the call.
|
|
19
|
+
*/
|
|
20
|
+
private readResponse;
|
|
21
|
+
/**
|
|
22
|
+
* Dispatch the notifications and server requests in `text`, and return the
|
|
23
|
+
* response to `requestId` — falling back to the first other response, which
|
|
24
|
+
* the caller's id check then rejects.
|
|
25
|
+
*/
|
|
26
|
+
private takeEnvelopes;
|
|
27
|
+
private sessionHeaders;
|
|
15
28
|
private handleNotification;
|
|
16
29
|
private refreshTools;
|
|
17
30
|
connect(): Promise<void>;
|
package/dist/wrap-tool.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Permission, Tool } from '@wrongstack/core/types';
|
|
2
2
|
import type { MCPClient } from './client.js';
|
|
3
3
|
import type { MCPTool } from './contracts.js';
|
|
4
|
+
import type { ElicitationRequester } from './elicitation.js';
|
|
4
5
|
/**
|
|
5
6
|
* Resolves the live client for a tool call. A plain {@link MCPClient} for eager
|
|
6
7
|
* servers, or a thunk that connects-on-demand for lazy/dormant servers (the
|
|
@@ -8,11 +9,12 @@ import type { MCPTool } from './contracts.js';
|
|
|
8
9
|
*/
|
|
9
10
|
export type MCPClientResolver = MCPClient | (() => Promise<MCPClient>);
|
|
10
11
|
export interface MCPToolCallObserver {
|
|
11
|
-
|
|
12
|
+
/** `caller` is the run making the call — who a server elicitation mid-call should ask. */
|
|
13
|
+
onStart(caller?: ElicitationRequester | undefined): void;
|
|
12
14
|
onFinish(result: {
|
|
13
15
|
durationMs: number;
|
|
14
16
|
ok: boolean;
|
|
15
|
-
}): void;
|
|
17
|
+
}, caller?: ElicitationRequester | undefined): void;
|
|
16
18
|
}
|
|
17
19
|
export declare function wrapMCPTool(serverName: string, mcpTool: MCPTool, client: MCPClientResolver, permission?: Permission, observer?: MCPToolCallObserver | undefined): Tool;
|
|
18
20
|
//# sourceMappingURL=wrap-tool.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.27",
|
|
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.27",
|
|
30
30
|
"undici": "^8.10.2"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|