@wrongstack/mcp 1.0.9 → 1.0.11

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.
@@ -13,6 +13,7 @@ export interface RegistryConnectContext {
13
13
  log: Logger;
14
14
  lazyMode: boolean;
15
15
  cacheDir?: string | undefined;
16
+ cwd?: string | undefined;
16
17
  authorizationProviderFactory?: MCPRegistryOptions['authorizationProviderFactory'] | undefined;
17
18
  operationListeners: Set<MCPOperationListener>;
18
19
  ensureConnected: (name: string) => Promise<MCPClient>;
@@ -1,6 +1,6 @@
1
1
  import type { MCPServerConfig, Tool } from '@wrongstack/core/types';
2
2
  import type { MCPClient } from './client.js';
3
- import type { ConnectionState } from './contracts.js';
3
+ import type { ConnectionState, MCPTool } from './contracts.js';
4
4
  import type { MCPServerOperationState } from './operations.js';
5
5
  import type { MCPPrompt, MCPResource, MCPResourceTemplate, MCPServerMetadata } from './protocol.js';
6
6
  export interface ServerSlot {
@@ -11,6 +11,16 @@ export interface ServerSlot {
11
11
  toolNames: string[];
12
12
  /** Cached tools when lazyMode is active (not registered in toolRegistry). */
13
13
  lazyTools: Tool[];
14
+ /**
15
+ * Raw tool list last learned from the server (live `tools/list` or the
16
+ * manifest cache). The manifest is written from THIS, never from
17
+ * `client.listTools()`: a write queued behind an idle sleep or crash runs
18
+ * after the client is gone, and persisting `[]` then would boot the server
19
+ * dormant with no tools — invisible until its config changes.
20
+ */
21
+ discoveredTools?: MCPTool[] | undefined;
22
+ /** Signature of the wrapped tool set, so an unchanged lazy wake does not re-register. */
23
+ toolSignature?: string | undefined;
14
24
  serverMetadata?: MCPServerMetadata | undefined;
15
25
  resources?: MCPResource[] | undefined;
16
26
  resourceTemplates?: MCPResourceTemplate[] | undefined;
@@ -10,6 +10,12 @@ export interface MCPRegistryOptions {
10
10
  events: EventBus;
11
11
  log: Logger;
12
12
  cacheDir?: string | undefined;
13
+ /**
14
+ * Working directory for stdio servers — the project root the host serves.
15
+ * Omitted: children inherit the process cwd (only correct for a host that
16
+ * runs from the project root).
17
+ */
18
+ cwd?: string | undefined;
13
19
  idleTimeoutMs?: number | undefined;
14
20
  lazyMode?: boolean | undefined;
15
21
  authorizationProviderFactory?: ((server: Readonly<MCPServerConfig>) => MCPAuthorizationProvider | undefined) | undefined;
@@ -16,6 +16,7 @@ export declare class MCPRegistry {
16
16
  private readonly log;
17
17
  private readonly lazyMode;
18
18
  private readonly cacheDir?;
19
+ private readonly cwd?;
19
20
  private readonly idleTimeoutMs;
20
21
  private readonly authorizationProviderFactory?;
21
22
  private readonly authorizationManager?;
@@ -65,12 +66,41 @@ export declare class MCPRegistry {
65
66
  * Returns the number of tools that were deactivated.
66
67
  */
67
68
  deactivateServer(name: string): number;
69
+ /**
70
+ * The tools a server offers — bare names, descriptions and input schemas —
71
+ * without activating, registering or waking it. In token-saving mode the
72
+ * model reaches MCP only through `mcp_use`, which needs the bare tool name
73
+ * and its input shape; before this there was no way to learn either short
74
+ * of guessing and reading the error. Honors `allowedTools`. Returns
75
+ * `undefined` for an unknown server, `[]` when nothing was discovered yet.
76
+ */
77
+ describeTools(name: string): {
78
+ name: string;
79
+ description?: string | undefined;
80
+ inputSchema: Record<string, unknown>;
81
+ }[] | undefined;
68
82
  /**
69
83
  * Check whether a server's tools are currently registered.
70
84
  */
71
85
  isActivated(name: string): boolean;
72
86
  stop(name: string): Promise<void>;
73
- restart(name: string): Promise<void>;
87
+ /**
88
+ * Stop and start a registered server. Pass `nextCfg` to apply an edited
89
+ * configuration: without it the slot reconnects with the config it was
90
+ * started with, so an update/enable routed through restart() silently kept
91
+ * the old command, url, env, permission and lazy flag until the next boot.
92
+ */
93
+ /**
94
+ * Put a running server to sleep while keeping its configuration enabled.
95
+ *
96
+ * A lazy server goes `dormant`: the process stops but its tools stay
97
+ * registered and the next call wakes it. Surfaces previously used stop() for
98
+ * this, which unregistered a lazy server's tools — "sleep" silently became
99
+ * "unreachable until restarted". Eager servers have no dormant state, so
100
+ * for them sleep is a stop.
101
+ */
102
+ sleep(name: string): Promise<void>;
103
+ restart(name: string, nextCfg?: MCPServerConfig | undefined): Promise<void>;
74
104
  list(): {
75
105
  name: string;
76
106
  state: ConnectionState;
@@ -1,6 +1,14 @@
1
1
  export declare class SSEReader {
2
2
  private buffer;
3
3
  private dataLines;
4
+ private eventName;
5
+ private endpointListeners;
6
+ /**
7
+ * Legacy HTTP+SSE transport: the server's first event is
8
+ * `event: endpoint` whose data is the (relative) URL to POST requests to.
9
+ * Its payload is a URL, not JSON, so it is dispatched separately.
10
+ */
11
+ onEndpoint(cb: (endpoint: string) => void): () => void;
4
12
  private listeners;
5
13
  onMessage(cb: (data: {
6
14
  jsonrpc?: string | undefined;
@@ -42,6 +42,8 @@ export declare class MCPVaultTokenStore {
42
42
  export declare class MCPRefreshingAuthorizationProvider implements MCPAuthorizationProvider {
43
43
  private readonly options;
44
44
  private refreshPromise?;
45
+ /** Refresh token the authorization server rejected; cleared by a new authorization. */
46
+ private rejectedRefreshToken?;
45
47
  private readonly resource;
46
48
  private readonly refreshSkewMs;
47
49
  constructor(options: MCPRefreshingAuthorizationProviderOptions);
@@ -1,3 +1,17 @@
1
1
  import type { MCPTool } from './contracts.js';
2
+ /**
3
+ * Collect every page of `tools/list`.
4
+ *
5
+ * The result carries `nextCursor` when a server paginates, and every transport
6
+ * used to read only the first page — a server with a large catalog silently
7
+ * lost the rest of its tools. Returns `null` when the FIRST page is a JSON-RPC
8
+ * error (callers keep their previous catalog instead of wiping it); a failure
9
+ * on a later page keeps the pages already collected. A transport exception on
10
+ * the first page propagates, as it did before.
11
+ */
12
+ export declare function listAllTools(requestPage: (params: Record<string, unknown>) => Promise<{
13
+ result?: unknown | undefined;
14
+ error?: unknown | undefined;
15
+ }>): Promise<MCPTool[] | null>;
2
16
  export declare function normalizeMCPTools(value: unknown): MCPTool[];
3
17
  //# sourceMappingURL=tool-schema.d.ts.map
@@ -15,6 +15,12 @@ type JsonRpcMethodEnvelope = {
15
15
  params?: unknown | undefined;
16
16
  };
17
17
  type JsonRpcEnvelope = JsonRpcResult | JsonRpcMethodEnvelope;
18
+ /**
19
+ * Encode an outgoing JSON-RPC message. A `notifications/*` method is a
20
+ * notification and MUST NOT carry an `id` — with one it is a request, which a
21
+ * strict server answers with an error (or never marks the session initialized).
22
+ */
23
+ export declare function encodeJsonRpcMessage(id: number, method: string, params: unknown): string;
18
24
  export declare function isJsonRpcResult(v: unknown): v is JsonRpcResult;
19
25
  /**
20
26
  * Extract JSON-RPC envelopes from a streamable-http response body. Handles BOTH
@@ -1,24 +1,46 @@
1
1
  import type { JsonRpcResponse, ToolCallResult } from './contracts.js';
2
2
  import { BaseHTTPTransport, type HttpTransportOptions } from './transport-base.js';
3
3
  /**
4
- * SSE transport for MCP over HTTP.
4
+ * SSE transport for MCP over HTTP (the 2024-11-05 "HTTP with SSE" transport).
5
5
  *
6
- * Uses native fetch API with ReadableStream to consume SSE events.
7
- * HTTP POST is used to send JSON-RPC requests.
6
+ * The client opens a GET event stream. A compliant server first sends
7
+ * `event: endpoint` naming the URL to POST JSON-RPC to, answers each POST with
8
+ * `202 Accepted`, and delivers the response over the stream. Servers that
9
+ * answer in the POST body instead are also supported: a JSON body is taken as
10
+ * the response, an empty/202 body waits for the stream.
8
11
  */
9
12
  export declare class SSETransport extends BaseHTTPTransport {
10
13
  private _nextId;
11
14
  private readerDone;
15
+ private closed;
12
16
  private readLoopAbort?;
13
17
  private reader?;
18
+ /** POST target announced by the server's `endpoint` event. */
19
+ private endpointUrl?;
20
+ /** Wakes connect() once the endpoint is known (or will not arrive). */
21
+ private streamSignal?;
22
+ /** Requests whose response is expected over the event stream, keyed by id. */
23
+ private readonly streamPending;
14
24
  constructor(opts: HttpTransportOptions);
15
25
  protected genId(): number;
16
26
  /** Refresh tool list when server sends notifications/tools/list_changed. */
17
27
  private handleToolsListChanged;
18
28
  connect(): Promise<void>;
29
+ /** Resolve once the stream announced its endpoint, emitted anything, ended, or the cap passed. */
30
+ private waitForStream;
31
+ /**
32
+ * Adopt the server's POST endpoint. It must stay on the configured origin:
33
+ * a cross-origin endpoint would move every request — Authorization header
34
+ * included — to a host that never passed configuration review.
35
+ */
36
+ private acceptEndpoint;
19
37
  private readSSEBody;
38
+ private rejectStreamPending;
20
39
  private buildSSEUrl;
40
+ /** Register interest in a stream-delivered response before the POST goes out. */
41
+ private awaitStreamResponse;
21
42
  private httpPost;
43
+ private postJsonRpc;
22
44
  callTool(name: string, input: unknown, opts?: {
23
45
  signal?: AbortSignal | undefined;
24
46
  }): Promise<ToolCallResult>;
@@ -7,6 +7,7 @@ import { BaseHTTPTransport, type HttpTransportOptions } from './transport-base.j
7
7
  */
8
8
  export declare class StreamableHTTPTransport extends BaseHTTPTransport {
9
9
  private _nextId;
10
+ private closed;
10
11
  private sessionId?;
11
12
  constructor(opts: HttpTransportOptions);
12
13
  protected genId(): number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/mcp",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
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.9",
29
+ "@wrongstack/core": "1.0.11",
30
30
  "undici": "^8.10.2"
31
31
  },
32
32
  "devDependencies": {