holon-sh 0.0.1-dev.3 → 0.0.1-dev.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "holon-sh",
3
- "version": "0.0.1-dev.3",
3
+ "version": "0.0.1-dev.4",
4
4
  "description": "Typed MCP clients and app view resources for Node.js.",
5
5
  "repository": {
6
6
  "type": "git",
package/protocol.d.ts CHANGED
@@ -1,9 +1,11 @@
1
- import type { CallToolRequest, CallToolResult, InputRequiredResult, InputResponses, ListToolsResult, RequestOptions } from "@modelcontextprotocol/client";
1
+ import type { CallToolRequest, CallToolResult, ClientCapabilities as McpClientCapabilities, InputRequiredResult, InputResponses, ListToolsResult, RequestOptions } from "@modelcontextprotocol/client";
2
2
 
3
3
  /** Bearer-token or OAuth provider accepted by the MCP transport. */
4
4
  export type AuthProvider =
5
5
  | { token(): Promise<string | undefined>; onUnauthorized?(context: unknown): Promise<void> }
6
6
  | { tokens(): unknown; redirectUrl: unknown; clientMetadata: unknown };
7
+ /** MCP client capabilities, such as `{ elicitation: { form: {} } }`. */
8
+ export type ClientCapabilities = McpClientCapabilities;
7
9
 
8
10
  /** MCP request options, including AbortSignal and timeout in milliseconds. Input-required responses are enabled by the runtime. */
9
11
  export type CallOptions = Omit<RequestOptions, "allowInputRequired">;
@@ -11,9 +13,11 @@ export type CallOptions = Omit<RequestOptions, "allowInputRequired">;
11
13
  export type CallMetadata = Omit<CallToolRequest["params"], "name" | "arguments"> & { inputResponses?: InputResponses; requestState?: string };
12
14
  /** @internal */
13
15
  type Fields<T> = { [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K] };
16
+ /** Successful tool result with contract-typed structured content. */
17
+ export type CompleteResult<Output> = Omit<Fields<CallToolResult>, "structuredContent" | "isError"> & { resultType: "complete"; isError?: false; structuredContent: Output };
14
18
  /** Full tool result: successful typed output, an application error, or an input-required continuation. */
15
19
  export type ToolResult<Output> =
16
- | (Omit<Fields<CallToolResult>, "structuredContent" | "isError"> & { resultType: "complete"; isError?: false; structuredContent: Output })
20
+ | CompleteResult<Output>
17
21
  | (Omit<Fields<CallToolResult>, "structuredContent" | "isError"> & { resultType: "complete"; isError: true; structuredContent?: unknown })
18
22
  | InputRequiredResult;
19
23
 
@@ -37,8 +41,8 @@ export interface ToolClient<I, O, R> {
37
41
  readonly read: (options?: CallOptions) => Promise<R[U]>;
38
42
  readonly watch: (onChange: (value: R[U]) => void | Promise<void>, options?: { signal?: AbortSignal }) => Promise<void>;
39
43
  } };
40
- /** Convenience methods returning structured output. Error or input-required results throw ToolCallError. Reserved object method names remain callable through callTool. */
41
- readonly tools: { readonly [K in Exclude<keyof I, "then" | "toJSON" | "toString" | "valueOf" | "toLocaleString">]: (input: I[K], options?: CallOptions) => Promise<K extends keyof O ? O[K] : unknown> };
44
+ /** Convenience methods returning structured output, or the complete result for a tool without an output schema. Error or input-required results throw ToolCallError. Reserved object method names remain callable through callTool. */
45
+ readonly tools: { readonly [K in Exclude<keyof I, "then" | "toJSON" | "toString" | "valueOf" | "toLocaleString">]: (input: I[K], options?: CallOptions) => Promise<K extends keyof O ? O[K] : CompleteResult<unknown>> };
42
46
  /** Return the full MCP result, preserving error and input-required results. Arguments and successful output are contract-validated. */
43
47
  readonly callTool: <K extends keyof I & string>(request: CallMetadata & { name: K; arguments: I[K] }, options?: CallOptions) => Promise<ToolResult<K extends keyof O ? O[K] : unknown>>;
44
48
  }
package/runtime.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import type { AuthProvider, CallOptions, ToolClient } from "./protocol.js";
1
+ import type { AuthProvider, CallOptions, ClientCapabilities, ToolClient } from "./protocol.js";
2
2
  export { ToolCallError } from "./protocol.js";
3
- export type { AuthProvider, CallOptions, CallMetadata, ToolResult, ToolClient } from "./protocol.js";
3
+ export type { AuthProvider, CallOptions, CallMetadata, ClientCapabilities, ToolResult, ToolClient } from "./protocol.js";
4
4
 
5
5
  /** Connection settings for an MCP endpoint. */
6
6
  export interface Binding {
@@ -14,6 +14,8 @@ export interface Binding {
14
14
  installationUID?: string;
15
15
  /** Close the session after every call instead of keeping one connection open. */
16
16
  scoped?: boolean;
17
+ /** Client capabilities declared to the server. On protocol 2026-07-28 every request carries them in `_meta["io.modelcontextprotocol/clientCapabilities"]` ([spec](https://modelcontextprotocol.io/specification/2026-07-28/client/elicitation#capabilities)); declare `{ elicitation: { form: {} } }` to receive form elicitations in input-required results. */
18
+ capabilities?: ClientCapabilities;
17
19
  }
18
20
  /** Alias for an endpoint binding. */
19
21
  export type EndpointBinding = Binding;
package/runtime.mjs CHANGED
@@ -71,7 +71,8 @@ export function createApps(identity, contracts, bindings, options) {
71
71
  const current = () => binding ?? (bindings ? undefined : resolve(name));
72
72
  let connection;
73
73
  const connect = resolved => {
74
- const client = new Client({ name: identity.name, version: identity.version }, { versionNegotiation: { mode: "auto" } });
74
+ // On 2026-07-28 the client sends these capabilities in every request's _meta: https://github.com/modelcontextprotocol/typescript-sdk/blob/fcef852f6cdafea07f36cf6fae69b37c8adf85be/packages/client/src/client/client.ts#L700-L711
75
+ const client = new Client({ name: identity.name, version: identity.version }, { capabilities: resolved.capabilities, versionNegotiation: { mode: "auto" } });
75
76
  const transport = new StreamableHTTPClientTransport(new URL(resolved.endpoint), { authProvider: resolved.authProvider, fetch: resolved.fetch, requestInit: { credentials: "include", redirect: "error", headers: resolved.installationUID ? { "X-Holon-Installation-UID": resolved.installationUID } : {} } });
76
77
  const current = { client, close: async () => {
77
78
  await transport.close();
@@ -131,7 +132,7 @@ export function createApps(identity, contracts, bindings, options) {
131
132
  tools[tool.name] = async (input, options) => {
132
133
  const result = await callTool({ name: tool.name, arguments: input }, options);
133
134
  if (result.resultType === "input_required" || result.isError) throw new ToolCallError(name, tool.name, result);
134
- return result.structuredContent;
135
+ return tool.outputSchema ? result.structuredContent : result;
135
136
  };
136
137
  }
137
138
  const resources = Object.create(null);