@smthrs/mcp 1.0.0-rc.3 → 1.0.0-rc.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/cjs/McpClient.js +1 -1
- package/dist/cjs/McpClient.js.map +1 -1
- package/dist/cjs/McpFlows.d.ts +3 -2
- package/dist/cjs/McpFlows.d.ts.map +1 -1
- package/dist/cjs/McpFlows.js.map +2 -2
- package/dist/esm/McpClient.js +1 -1
- package/dist/esm/McpClient.js.map +1 -1
- package/dist/esm/McpFlows.d.ts +3 -2
- package/dist/esm/McpFlows.d.ts.map +1 -1
- package/dist/esm/McpFlows.js +3 -2
- package/dist/esm/McpFlows.js.map +1 -1
- package/package.json +9 -9
- package/src/McpClient.ts +1 -1
- package/src/McpFlows.ts +3 -2
package/dist/cjs/McpClient.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/McpClient.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * A minimal MCP client covering the `initialize` handshake, `tools/list`, and\n * `tools/call`, over stdio or Streamable HTTP.\n *\n * This is deliberately not a general MCP SDK. Smithers has exactly one\n * consumer of an MCP session: {@link McpFlows}, which needs a tool catalog\n * and a way to invoke one entry from it, so the client exposes only that.\n * Resources, prompts, sampling, and roots are not wired up; add them here\n * when a flow adapter needs them, not speculatively.\n *\n * @since 1.0.0-rc.0\n */\n\nimport { isRecord } from \"@smthrs/canonical/Record\"\nimport { Effect, Exit, Result, Schema, Scope } from \"effect\"\nimport type * as HttpClient from \"effect/unstable/http/HttpClient\"\nimport type { ChildProcessSpawner } from \"effect/unstable/process/ChildProcessSpawner\"\nimport * as DiagnosticReporter from \"./internal/DiagnosticReporter.ts\"\nimport * as HttpTransport from \"./internal/HttpTransport.ts\"\nimport * as JsonLimits from \"./internal/JsonLimits.ts\"\nimport * as Limits from \"./internal/Limits.ts\"\nimport * as StdioTransport from \"./internal/StdioTransport.ts\"\nimport * as Transport from \"./internal/Transport.ts\"\nimport { McpError } from \"./McpError.ts\"\n\n/**\n * One remote tool as the server describes it.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface ToolDescription {\n readonly name: string\n readonly description: string | undefined\n /** The tool's parameter shape, as a JSON Schema document with `type: \"object\"`. */\n readonly inputSchema: Record<string, unknown>\n /** The tool's structured result shape, when the server disclosed one. */\n readonly outputSchema: Record<string, unknown> | undefined\n}\n\n/**\n * The result of one `tools/call`.\n *\n * MCP tool content is a small union (text, image, embedded resource, \u2026); this\n * client passes every block through by shape rather than modeling the union,\n * since {@link McpFlows} only needs to hand the blocks back to the caller.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface ToolResult {\n readonly content: ReadonlyArray<Record<string, unknown>>\n readonly isError: boolean\n readonly structuredContent: Record<string, unknown> | undefined\n}\n\n/**\n * A live MCP session, holding the tool catalog fetched at connect time and a\n * way to call one of its entries.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface McpClient {\n readonly server: string\n readonly tools: ReadonlyArray<ToolDescription>\n /**\n * Calls one catalogued tool. An unknown name fails with `tool_not_found`\n * before a JSON-RPC frame is written. Declared structured output is checked\n * against the supported output-schema subset before it is returned.\n */\n readonly callTool: (name: string, args: Record<string, unknown>) => Effect.Effect<ToolResult, McpError>\n}\n\n/**\n * Session and catalog limits shared by every transport.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface ClientOptions {\n /** The name this server is known by, for flow naming and error messages. */\n readonly server: string\n /** Deadline for each initialize/catalog request. See {@link defaultHandshakeTimeoutMs}. */\n readonly handshakeTimeoutMs?: number | undefined\n /** Maximum tools accepted across every catalog page. See {@link defaultMaxTools}. */\n readonly maxTools?: number | undefined\n /**\n * Maximum UTF-8 bytes in a tool name. Names also cannot be `.` or `..`, or\n * contain `/`, a control or format character (Unicode categories Cc and Cf,\n * which include bidi and zero-width marks), U+2028, U+2029, or a lone\n * surrogate. See {@link defaultMaxToolNameBytes}.\n */\n readonly maxToolNameBytes?: number | undefined\n /**\n * Maximum UTF-8 bytes of one tool's model-facing text: its description plus\n * its JSON-encoded `inputSchema`. See {@link defaultMaxToolDocumentBytes}.\n */\n readonly maxToolDocumentBytes?: number | undefined\n /** Maximum pages walked while fetching the catalog. See {@link defaultMaxCatalogPages}. */\n readonly maxCatalogPages?: number | undefined\n}\n\n/**\n * A server spawned as a child process and spoken to over its stdio.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface StdioConnectOptions extends StdioTransport.ConnectOptions, ClientOptions {\n readonly url?: never\n}\n\n/**\n * Supplies the bearer credential for a Streamable HTTP server. `token` runs\n * once per HTTP message, so a provider can rotate the credential; its failure\n * fails that message unchanged.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport type AuthProvider = HttpTransport.AuthProvider\n\n/**\n * A remote server reached over MCP Streamable HTTP through the `HttpClient`\n * in context.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface HttpConnectOptions extends HttpTransport.ConnectOptions, ClientOptions {\n readonly command?: never\n}\n\n/**\n * Options accepted by {@link connect}: a stdio command or an HTTP `url`.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type ConnectOptions = StdioConnectOptions | HttpConnectOptions\n\n/**\n * The services {@link connect} needs for the given options: a process spawner\n * for stdio, an `HttpClient` for a `url`.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport type Requirements<O extends ConnectOptions> = O extends { readonly url: string } ? HttpClient.HttpClient\n : ChildProcessSpawner\n\nconst isHttp = (options: ConnectOptions): options is HttpConnectOptions => options.url !== undefined\n\nconst PositiveInteger = Schema.Int.check(Schema.isGreaterThan(0))\n\n/**\n * Authoritative decoder for a persisted stdio MCP server entry.\n *\n * The schema requires non-empty server and command names, string arguments,\n * a plain string-valued environment record, and positive-integer limits.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const ConnectOptionsSchema = Schema.Struct({\n server: Schema.NonEmptyString,\n command: Schema.NonEmptyString,\n args: Schema.Array(Schema.String),\n cwd: Schema.optional(Schema.NonEmptyString),\n env: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n handshakeTimeoutMs: Schema.optional(PositiveInteger),\n requestTimeoutMs: Schema.optional(PositiveInteger),\n queueCapacity: Schema.optional(PositiveInteger),\n maxFrameBytes: Schema.optional(PositiveInteger),\n maxOutboundFrameBytes: Schema.optional(PositiveInteger),\n maxStderrBytes: Schema.optional(PositiveInteger),\n maxTools: Schema.optional(PositiveInteger),\n maxToolNameBytes: Schema.optional(PositiveInteger),\n maxToolDocumentBytes: Schema.optional(PositiveInteger),\n maxCatalogPages: Schema.optional(PositiveInteger)\n})\n\n/** An absolute `http:` or `https:` URL without credentials: userinfo would put a secret in the file. */\nconst isEndpoint = (url: string): boolean => {\n if (!URL.canParse(url)) return false\n const parsed = new URL(url)\n return (parsed.protocol === \"http:\" || parsed.protocol === \"https:\") && parsed.username === \"\" &&\n parsed.password === \"\"\n}\n\n/**\n * Authoritative decoder for a persisted Streamable HTTP MCP server entry.\n *\n * The schema requires a non-empty server name, an absolute `http:` or\n * `https:` `url` without userinfo, and positive-integer limits. A bearer\n * credential is never stored in the entry: `bearerTokenEnv` names the\n * environment variable the host reads it from and turns into an\n * {@link AuthProvider}.\n *\n * @category schemas\n * @since 1.0.0-rc.1\n */\nexport const HttpConnectOptionsSchema = Schema.Struct({\n server: Schema.NonEmptyString,\n url: Schema.String.check(Schema.makeFilter(isEndpoint, { expected: \"an http: or https: URL without credentials\" })),\n bearerTokenEnv: Schema.optionalKey(Schema.String.check(Schema.isPattern(/^[A-Za-z_][A-Za-z0-9_]*$/))),\n handshakeTimeoutMs: Schema.optional(PositiveInteger),\n requestTimeoutMs: Schema.optional(PositiveInteger),\n maxFrameBytes: Schema.optional(PositiveInteger),\n maxOutboundFrameBytes: Schema.optional(PositiveInteger),\n maxTools: Schema.optional(PositiveInteger),\n maxToolNameBytes: Schema.optional(PositiveInteger),\n maxToolDocumentBytes: Schema.optional(PositiveInteger),\n maxCatalogPages: Schema.optional(PositiveInteger)\n})\n\n/**\n * Frozen identity disclosed to every MCP server during initialization.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const clientInfo: { readonly name: string; readonly version: string } = Object.freeze({\n name: \"smithers\",\n version: \"1.0.0-rc.3\"\n})\n\n/**\n * MCP revisions whose `tools/list` and `tools/call` shapes this client\n * decodes. The frozen list always proposes `2025-06-18` first.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const supportedProtocolVersions: ReadonlyArray<string> = Object.freeze([\n \"2025-06-18\",\n \"2025-03-26\",\n \"2024-11-05\"\n])\n\n/**\n * Default deadline for each MCP handshake request.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultHandshakeTimeoutMs = 10_000\n\n/**\n * Default deadline for each tool request.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultRequestTimeoutMs = Transport.defaultRequestTimeoutMs\n\n/**\n * Default number of outbound frames allowed to wait in memory.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultQueueCapacity = StdioTransport.defaultQueueCapacity\n\n/**\n * Default maximum inbound JSON-RPC frame size.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxFrameBytes = Transport.defaultMaxFrameBytes\n\n/**\n * Default maximum outbound JSON-RPC frame size.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxOutboundFrameBytes = Transport.defaultMaxOutboundFrameBytes\n\n/**\n * Default maximum child-stderr tail retained for connection diagnostics.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxStderrBytes = StdioTransport.defaultMaxStderrBytes\n\n/**\n * Default maximum number of tools in a remote catalog.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxTools = 256\n\n/**\n * Default maximum UTF-8 byte length of one remote tool name.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxToolNameBytes = 128\n\n/**\n * Default maximum UTF-8 bytes of one tool's description plus its JSON-encoded\n * `inputSchema`, the server-authored text a model reads for that tool.\n *\n * @category constants\n * @since 1.0.0-rc.1\n */\nexport const defaultMaxToolDocumentBytes = 65_536\n\n/**\n * Default maximum number of remote catalog pages.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxCatalogPages = 32\n\n/**\n * Maximum nested JSON containers, including the JSON-RPC envelope. Fixed so\n * accepted server schemas and values remain safe for recursive consumers.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const maxJsonDepth = JsonLimits.maxDepth\n\nconst invalidResponse = (server: string, message: string): McpError =>\n new McpError({ code: \"invalid_response\", message, server })\n\nconst asInitialize = (server: string, result: unknown): Result.Result<void, McpError> => {\n if (!isRecord(result)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: result is not an object`\n ))\n }\n if (typeof result.protocolVersion !== \"string\") {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: protocolVersion is not a string`\n ))\n }\n if (!supportedProtocolVersions.includes(result.protocolVersion)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" speaks an unsupported protocol version; this client speaks ${\n supportedProtocolVersions.join(\", \")\n }`\n ))\n }\n if (!isRecord(result.capabilities)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: capabilities is not an object`\n ))\n }\n if (!Object.hasOwn(result.capabilities, \"tools\") || !isRecord(result.capabilities.tools)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" does not serve tools: its initialize result declares no tools capability`\n ))\n }\n return Result.succeed(undefined)\n}\n\ntype CatalogLimits = {\n readonly maxTools: number\n readonly maxToolNameBytes: number\n readonly maxToolDocumentBytes: number\n}\n\ntype ToolPage = {\n readonly nextCursor: string | undefined\n}\n\nconst nameEncoder = new TextEncoder()\n\n// Cc covers C0, DEL, and C1. Cf covers bidi overrides and isolates (U+202A-202E,\n// U+2066-2069), zero-width marks (U+200B-200F, U+2060, U+FEFF), and soft hyphen:\n// all invisible text that makes `mcp/<server>/<tool>` read as another tool.\n// Cs catches a lone surrogate, which UTF-8 encoding would silently replace.\nconst forbiddenToolNameCharacter = /[/\\p{Cc}\\p{Cf}\\p{Cs}\\u2028\\u2029]/u\n\nconst isForbiddenToolName = (name: string): boolean =>\n name === \".\" || name === \"..\" || forbiddenToolNameCharacter.test(name)\n\nconst asToolPage = (\n server: string,\n result: unknown,\n limits: CatalogLimits,\n seen: Set<string>,\n described: Array<ToolDescription>\n): Result.Result<ToolPage, McpError> => {\n const tools = isRecord(result) ? result.tools : undefined\n if (!Array.isArray(tools)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/list result with no tools array`\n ))\n }\n for (const [index, tool] of tools.entries()) {\n if (described.length >= limits.maxTools) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned more than ${limits.maxTools} tools`\n ))\n }\n if (!isRecord(tool)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned tools[${index}], which is not an object`\n ))\n }\n const record = tool\n if (typeof record.name !== \"string\" || record.name === \"\") {\n return Result.fail(invalidResponse(server, `MCP server \"${server}\" returned tools[${index}] with no name`))\n }\n if (nameEncoder.encode(record.name).byteLength > limits.maxToolNameBytes) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool name longer than ${limits.maxToolNameBytes} bytes`\n ))\n }\n if (isForbiddenToolName(record.name)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool name that is \".\" or \"..\", or contains \"/\" or an invisible or control character`\n ))\n }\n if (seen.has(record.name)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a duplicate tool name at catalog index ${index}`\n ))\n }\n if (!isRecord(record.inputSchema) || record.inputSchema.type !== \"object\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool whose inputSchema is not a JSON Schema object of type \"object\"`\n ))\n }\n const description = typeof record.description === \"string\" ? record.description : undefined\n const documentBytes = nameEncoder.encode(description ?? \"\").byteLength +\n nameEncoder.encode(JSON.stringify(record.inputSchema)).byteLength\n if (documentBytes > limits.maxToolDocumentBytes) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool description and inputSchema longer than ${limits.maxToolDocumentBytes} bytes`\n ))\n }\n let outputSchema: Record<string, unknown> | undefined\n if (Object.hasOwn(record, \"outputSchema\")) {\n if (!isRecord(record.outputSchema)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool whose outputSchema is not a JSON object`\n ))\n }\n outputSchema = record.outputSchema\n }\n seen.add(record.name)\n described.push({\n name: record.name,\n description,\n inputSchema: record.inputSchema,\n outputSchema\n })\n }\n\n const nextCursor = isRecord(result) && Object.hasOwn(result, \"nextCursor\") ? result.nextCursor : undefined\n if (nextCursor === undefined) return Result.succeed({ nextCursor: undefined })\n if (typeof nextCursor !== \"string\" || nextCursor === \"\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/list cursor that is not a non-empty string`\n ))\n }\n return Result.succeed({ nextCursor })\n}\n\n// Container guards deliberately inspect only the shape; traversal below owns\n// cooperative interruption. Schema.Int excludes unsafe integers, unlike JSON Schema.\nconst outputTypes = {\n null: Schema.Null,\n boolean: Schema.Boolean,\n object: Schema.declare(isRecord),\n array: Schema.declare(Array.isArray),\n number: Schema.Number,\n string: Schema.String,\n integer: Schema.Number.check(Schema.makeFilter(Number.isInteger))\n}\n\n// Every traversal step consumes a slice slot, including enum-key construction.\n// Yielding keeps validation interruptible after the transport has completed.\nconst runJsonWork = <A>(work: Generator<void, A>): Effect.Effect<A> =>\n Effect.gen(function*() {\n while (true) {\n for (let steps = 0; steps < 1_024; steps += 1) {\n const next = work.next()\n if (next.done) return next.value\n }\n yield* Effect.yieldNow\n }\n })\n\n// Keys are canonical JSON: object order is irrelevant, array order is not.\n// Inputs here are depth-checked parsed JSON, never caller-owned arguments.\nconst enumKey = function*(value: unknown): Generator<void, string> {\n yield\n if (Array.isArray(value)) {\n const items: Array<string> = []\n for (const item of value) items.push(yield* enumKey(item))\n return `[${items.join(\",\")}]`\n }\n if (isRecord(value)) {\n const members: Array<string> = []\n for (const key of Object.keys(value).sort()) {\n members.push(`${JSON.stringify(key)}:${yield* enumKey(value[key])}`)\n }\n return `{${members.join(\",\")}}`\n }\n return JSON.stringify(value)\n}\n\ntype OutputValidator = (value: unknown, path: string) => Generator<void, JsonIssue | undefined>\n\n/**\n * Compile the supported output-schema subset once per catalog. Effect Schema\n * owns type unions; this cooperative compatibility traversal retains composite\n * enums, own-property requirements and ignored unsupported keywords. Importing\n * the whole document would enforce constraints this client does not support.\n */\nconst compileOutputSchema = function*(schema: Record<string, unknown>): Generator<void, OutputValidator> {\n yield\n const types = new Set<keyof typeof outputTypes>()\n for (const candidate of Array.isArray(schema.type) ? schema.type : [schema.type]) {\n yield\n if (typeof candidate === \"string\" && Object.hasOwn(outputTypes, candidate)) {\n types.add(candidate as keyof typeof outputTypes)\n }\n }\n const accepts = Schema.is(\n types.size === 0 ? Schema.Unknown : Schema.Union([...types].map((type) => outputTypes[type]))\n )\n const typeReason = `expected ${[...types].join(\" or \")}`\n let enumIndex: Set<string> | undefined\n if (Array.isArray(schema.enum)) {\n enumIndex = new Set()\n for (const member of schema.enum) enumIndex.add(yield* enumKey(member))\n }\n const required: Array<string> = []\n if (Array.isArray(schema.required)) {\n for (const key of schema.required) {\n yield\n if (typeof key === \"string\") required.push(key)\n }\n }\n const properties: Array<readonly [string, OutputValidator]> = []\n if (isRecord(schema.properties)) {\n for (const [key, property] of Object.entries(schema.properties)) {\n yield\n if (isRecord(property)) properties.push([key, yield* compileOutputSchema(property)])\n }\n }\n const items = isRecord(schema.items) ? yield* compileOutputSchema(schema.items) : undefined\n\n return function*(value, path) {\n yield\n if (enumIndex !== undefined && !enumIndex.has(yield* enumKey(value))) {\n return { path, reason: \"expected a declared enum value\" }\n }\n if (!accepts(value)) return { path, reason: typeReason }\n if (isRecord(value)) {\n for (const key of required) {\n yield\n if (!Object.hasOwn(value, key)) return { path: `${path}.${key}`, reason: \"required property is missing\" }\n }\n for (const [key, validate] of properties) {\n yield\n if (!Object.hasOwn(value, key)) continue\n const issue = yield* validate(value[key], `${path}.${key}`)\n if (issue !== undefined) return issue\n }\n }\n if (Array.isArray(value) && items !== undefined) {\n for (const [index, item] of value.entries()) {\n const issue = yield* items(item, `${path}[${index}]`)\n if (issue !== undefined) return issue\n }\n }\n return undefined\n }\n}\n\nconst asToolResult = function*(\n server: string,\n result: unknown,\n outputSchema: Record<string, unknown> | undefined,\n diagnostic: (source: \"invalid-response\", detail: unknown) => void,\n validate: OutputValidator | undefined\n): Generator<void, Result.Result<ToolResult, McpError>> {\n if (!isRecord(result)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result that is not an object`\n ))\n }\n const hasContent = Object.hasOwn(result, \"content\")\n const hasStructuredContent = Object.hasOwn(result, \"structuredContent\")\n if (!hasContent && !hasStructuredContent) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result with no content array`\n ))\n }\n if (hasContent && !Array.isArray(result.content)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result with no content array`\n ))\n }\n const content: Array<Record<string, unknown>> = []\n const blocks = hasContent ? result.content as Array<unknown> : []\n for (const [index, block] of blocks.entries()) {\n yield\n if (!isRecord(block)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose content[${index}] is not an object`\n ))\n }\n content.push(block)\n }\n if (Object.hasOwn(result, \"isError\") && typeof result.isError !== \"boolean\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose isError is not a boolean`\n ))\n }\n let structuredContent: Record<string, unknown> | undefined\n if (hasStructuredContent) {\n if (!isRecord(result.structuredContent)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose structuredContent is not a JSON object`\n ))\n }\n structuredContent = result.structuredContent\n if (validate !== undefined) {\n const issue = yield* validate(structuredContent, \"structuredContent\")\n if (issue !== undefined) {\n diagnostic(\"invalid-response\", { issue, outputSchema })\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned structuredContent that its own outputSchema rejects: ${issue.reason}; property path withheld`\n ))\n }\n }\n }\n return Result.succeed({\n content,\n isError: result.isError === true,\n structuredContent\n })\n}\n\ninterface JsonObject {\n [key: string]: JsonValue\n}\n\ntype JsonValue = null | boolean | number | string | Array<JsonValue> | JsonObject\n\ntype JsonIssue = {\n readonly path: string\n readonly reason: string\n}\n\ntype JsonPath = string | { readonly parent: JsonPath; key: string | number }\n\nconst renderJsonPath = (path: JsonPath): string =>\n typeof path === \"string\" ?\n path :\n `${renderJsonPath(path.parent)}${typeof path.key === \"number\" ? `[${path.key}]` : `.${path.key}`}`\n\nconst jsonFailure = (path: JsonPath, reason: string): Result.Result<JsonValue, JsonIssue> =>\n Result.fail({ path: renderJsonPath(path), reason })\n\nconst reflect = <A>(thunk: () => A): Result.Result<A, string> => {\n try {\n return Result.succeed(thunk())\n } catch {\n return Result.fail(\"a property that threw when read\")\n }\n}\n\nconst ownDescriptors = (object: object): Result.Result<PropertyDescriptorMap, string> =>\n reflect(() => Object.getOwnPropertyDescriptors(object))\n\nconst isAccessor = (descriptor: PropertyDescriptor): boolean =>\n Object.hasOwn(descriptor, \"get\") || Object.hasOwn(descriptor, \"set\")\n\ntype JsonBudget = { remaining: number }\n\n// Lower bounds on encoded size avoid expanding repeated references into an\n// enormous tree before the transport's exact UTF-8 frame check. String/key\n// UTF-16 length is a lower bound even with escapes and surrogate pairs.\nconst spendJson = (budget: JsonBudget, bytes: number): boolean => {\n budget.remaining -= bytes\n return budget.remaining >= 0\n}\n\nconst snapshotJson = (\n value: unknown,\n path: JsonPath,\n ancestors: Set<object>,\n budget: JsonBudget\n): Result.Result<JsonValue, JsonIssue> => {\n const bytes = typeof value === \"string\" ?\n value.length + 2\n : typeof value === \"number\" || typeof value === \"boolean\" ?\n String(value).length\n : value === null ?\n 4\n : 2\n if (!spendJson(budget, bytes)) return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n if (value === null) return Result.succeed(null)\n if (typeof value === \"boolean\" || typeof value === \"string\") return Result.succeed(value)\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? Result.succeed(value) : jsonFailure(path, \"a non-finite number\")\n }\n if (typeof value === \"undefined\") return jsonFailure(path, \"undefined\")\n if (typeof value === \"bigint\") return jsonFailure(path, \"a bigint\")\n if (typeof value === \"function\") return jsonFailure(path, \"a function\")\n if (typeof value === \"symbol\") return jsonFailure(path, \"a symbol\")\n\n if (ancestors.has(value)) return jsonFailure(path, \"a cyclic reference\")\n // Arguments live inside the wire envelope and its params object.\n if (ancestors.size + 3 > maxJsonDepth) return jsonFailure(path, `JSON nesting exceeds ${maxJsonDepth} containers`)\n const array = reflect(() => Array.isArray(value))\n if (Result.isFailure(array)) return jsonFailure(path, array.failure)\n if (array.success) {\n const length = reflect(() => (value as Array<unknown>).length)\n if (Result.isFailure(length)) return jsonFailure(path, length.failure)\n if (!Number.isSafeInteger(length.success) || length.success < 0) {\n return jsonFailure(path, \"a property that threw when read\")\n }\n if (!spendJson(budget, Math.max(0, length.success - 1))) {\n return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n }\n const descriptors = ownDescriptors(value)\n if (Result.isFailure(descriptors)) return jsonFailure(path, descriptors.failure)\n ancestors.add(value)\n const copied: Array<JsonValue> = []\n const memberPath: JsonPath = { parent: path, key: 0 }\n for (let index = 0; index < length.success; index += 1) {\n memberPath.key = index\n // Missing slots must not resolve through Object.prototype.\n const descriptor = Object.hasOwn(descriptors.success, index) ? descriptors.success[index] : undefined\n if (descriptor !== undefined && isAccessor(descriptor)) {\n ancestors.delete(value)\n return jsonFailure(memberPath, \"an accessor property\")\n }\n const member = descriptor === undefined ? undefined : descriptor.value\n const snapshot = snapshotJson(member, memberPath, ancestors, budget)\n if (Result.isFailure(snapshot)) {\n ancestors.delete(value)\n return snapshot\n }\n copied.push(snapshot.success)\n }\n ancestors.delete(value)\n return Result.succeed(copied)\n }\n\n const object = value as Record<string, unknown>\n const prototype = reflect(() => Object.getPrototypeOf(object))\n if (Result.isFailure(prototype)) return jsonFailure(path, prototype.failure)\n if (prototype.success !== Object.prototype && prototype.success !== null) {\n return jsonFailure(path, \"an object with a non-plain prototype\")\n }\n const symbols = reflect(() => Object.getOwnPropertySymbols(object))\n if (Result.isFailure(symbols)) return jsonFailure(path, symbols.failure)\n const descriptors = ownDescriptors(object)\n if (Result.isFailure(descriptors)) return jsonFailure(path, descriptors.failure)\n for (const key of symbols.success) {\n if (Object.hasOwn(descriptors.success, key) && descriptors.success[key]!.enumerable) {\n return jsonFailure(path, \"a symbol-keyed property\")\n }\n }\n\n ancestors.add(object)\n const copied: JsonObject = {}\n let members = 0\n const memberPath: JsonPath = { parent: path, key: \"\" }\n for (const key of Object.keys(descriptors.success)) {\n memberPath.key = key\n const descriptor = descriptors.success[key]!\n if (descriptor.enumerable !== true) continue\n if (!spendJson(budget, key.length + 3 + Math.min(1, members++))) {\n ancestors.delete(object)\n return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n }\n if (isAccessor(descriptor)) {\n ancestors.delete(object)\n return jsonFailure(memberPath, \"an accessor property\")\n }\n const snapshot = snapshotJson(descriptor.value, memberPath, ancestors, budget)\n if (Result.isFailure(snapshot)) {\n ancestors.delete(object)\n return snapshot\n }\n Object.defineProperty(copied, key, {\n configurable: true,\n enumerable: true,\n value: snapshot.success,\n writable: true\n })\n }\n ancestors.delete(object)\n return Result.succeed(copied)\n}\n\nconst snapshotArguments = (\n server: string,\n args: Record<string, unknown>,\n diagnostic: (source: \"invalid-arguments\", detail: unknown) => void,\n maxBytes: number\n): Result.Result<Record<string, unknown>, McpError> => {\n const snapshot = snapshotJson(args, \"arguments\", new Set(), { remaining: maxBytes })\n if (Result.isFailure(snapshot)) {\n diagnostic(\"invalid-arguments\", snapshot.failure)\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" was sent a tool argument that is not JSON: ${snapshot.failure.reason}; property path withheld`\n ))\n }\n if (!isRecord(snapshot.success)) {\n return Result.fail(Limits.protocolError(server, `MCP server \"${server}\" tool arguments must be a JSON object`))\n }\n return Result.succeed(snapshot.success)\n}\n\n/**\n * Connects to an MCP server over stdio (`command`) or Streamable HTTP (`url`),\n * completes the `initialize` handshake, and fetches its tool catalog once, up\n * front. Failed or interrupted setup closes its subprocess, I/O fibers, or\n * HTTP session before returning to the caller; a successful session stays\n * open until the caller scope closes.\n *\n * The tool catalog is a snapshot: a server that changes its tools after\n * connecting (a `notifications/tools/list_changed` push) is not re-polled.\n * {@link McpFlows} rebuilds by reconnecting to refresh.\n * Catalog input schemas must declare `type: \"object\"`. A later tool result may\n * omit `content` when it carries `structuredContent`; a declared output schema\n * is enforced for the documented keyword subset.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const connect = <O extends ConnectOptions>(\n options: O\n): Effect.Effect<McpClient, McpError, Requirements<O> | Scope.Scope> =>\n Effect.acquireUseRelease(\n Effect.flatMap(Effect.scope, Scope.fork),\n (scope) =>\n Effect.gen(function*() {\n const diagnostic = yield* DiagnosticReporter.make(options.server)\n const decodeResponse = <A>(response: unknown, decoded: Result.Result<A, McpError>) =>\n Effect.fromResult(decoded).pipe(\n Effect.tapError(() => Effect.sync(() => diagnostic(\"invalid-response\", response)))\n )\n const handshakeTimeoutMs = options.handshakeTimeoutMs ?? defaultHandshakeTimeoutMs\n const maxArgumentBytes = options.maxOutboundFrameBytes ?? defaultMaxOutboundFrameBytes\n const maxTools = options.maxTools ?? defaultMaxTools\n const maxToolNameBytes = options.maxToolNameBytes ?? defaultMaxToolNameBytes\n const maxToolDocumentBytes = options.maxToolDocumentBytes ?? defaultMaxToolDocumentBytes\n const maxCatalogPages = options.maxCatalogPages ?? defaultMaxCatalogPages\n yield* Limits.checkPositiveIntegers(options.server, [\n [\"handshakeTimeoutMs\", handshakeTimeoutMs],\n [\"maxTools\", maxTools],\n [\"maxToolNameBytes\", maxToolNameBytes],\n [\"maxToolDocumentBytes\", maxToolDocumentBytes],\n [\"maxCatalogPages\", maxCatalogPages]\n ])\n\n const transport: Transport.Transport = yield* (isHttp(options)\n ? HttpTransport.connect(options)\n : StdioTransport.connect(options))\n\n const initialized = yield* transport.request(\n \"initialize\",\n {\n protocolVersion: supportedProtocolVersions[0],\n capabilities: {},\n clientInfo\n },\n handshakeTimeoutMs\n )\n yield* decodeResponse(initialized, asInitialize(options.server, initialized))\n // A notification, not a request: the server never replies to it, and the\n // handshake is not complete until the client sends it.\n yield* transport.notify(\"notifications/initialized\", undefined, handshakeTimeoutMs)\n\n const tools: Array<ToolDescription> = []\n const toolNames = new Set<string>()\n const cursors = new Set<string>()\n let params: Record<string, unknown> = {}\n let pageCount = 0\n while (true) {\n const listed = yield* transport.request(\"tools/list\", params, handshakeTimeoutMs)\n pageCount += 1\n const page = yield* decodeResponse(\n listed,\n asToolPage(\n options.server,\n listed,\n { maxTools, maxToolNameBytes, maxToolDocumentBytes },\n toolNames,\n tools\n )\n )\n if (page.nextCursor === undefined) break\n if (cursors.has(page.nextCursor)) {\n diagnostic(\"invalid-response\", listed)\n return yield* Effect.fail(invalidResponse(\n options.server,\n `MCP server \"${options.server}\" repeated a tools/list cursor`\n ))\n }\n if (pageCount >= maxCatalogPages) {\n return yield* Effect.fail(invalidResponse(\n options.server,\n `MCP server \"${options.server}\" returned more than ${maxCatalogPages} tools/list pages`\n ))\n }\n cursors.add(page.nextCursor)\n params = { cursor: page.nextCursor }\n }\n JsonLimits.freezeParsed(tools)\n const validators = new Map<string, OutputValidator>()\n for (const tool of tools) {\n if (tool.outputSchema !== undefined) {\n validators.set(tool.name, yield* runJsonWork(compileOutputSchema(tool.outputSchema)))\n }\n }\n\n const callTool = (name: string, args: Record<string, unknown>): Effect.Effect<ToolResult, McpError> => {\n const tool = tools.find((candidate) => candidate.name === name)\n if (tool === undefined) {\n return Effect.fail(\n new McpError({\n code: \"tool_not_found\",\n message: `MCP server \"${options.server}\" has no requested tool`,\n server: options.server\n })\n )\n }\n const snapshot = snapshotArguments(options.server, args, diagnostic, maxArgumentBytes)\n if (Result.isFailure(snapshot)) {\n // Do not inspect the rejected object again: it may contain throwing\n // accessors or proxies. Even diagnostic observers see only the safe\n // rejection, never a second traversal of executable user properties.\n return Effect.fail(snapshot.failure)\n }\n return Effect.flatMap(\n transport.request(\"tools/call\", { name, arguments: snapshot.success }),\n (result) =>\n Effect.flatMap(\n runJsonWork(asToolResult(options.server, result, tool.outputSchema, diagnostic, validators.get(name))),\n (decoded) => decodeResponse(result, decoded)\n )\n )\n }\n\n return { server: options.server, tools, callTool }\n }).pipe(Scope.provide(scope)),\n // Closing a failed attempt also detaches it from the caller's scope.\n // Successful sessions remain owned by that scope until it closes.\n (scope, exit) => Exit.isFailure(exit) ? Scope.close(scope, exit) : Effect.void\n ) as Effect.Effect<McpClient, McpError, Requirements<O> | Scope.Scope>\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * A minimal MCP client covering the `initialize` handshake, `tools/list`, and\n * `tools/call`, over stdio or Streamable HTTP.\n *\n * This is deliberately not a general MCP SDK. Smithers has exactly one\n * consumer of an MCP session: {@link McpFlows}, which needs a tool catalog\n * and a way to invoke one entry from it, so the client exposes only that.\n * Resources, prompts, sampling, and roots are not wired up; add them here\n * when a flow adapter needs them, not speculatively.\n *\n * @since 1.0.0-rc.0\n */\n\nimport { isRecord } from \"@smthrs/canonical/Record\"\nimport { Effect, Exit, Result, Schema, Scope } from \"effect\"\nimport type * as HttpClient from \"effect/unstable/http/HttpClient\"\nimport type { ChildProcessSpawner } from \"effect/unstable/process/ChildProcessSpawner\"\nimport * as DiagnosticReporter from \"./internal/DiagnosticReporter.ts\"\nimport * as HttpTransport from \"./internal/HttpTransport.ts\"\nimport * as JsonLimits from \"./internal/JsonLimits.ts\"\nimport * as Limits from \"./internal/Limits.ts\"\nimport * as StdioTransport from \"./internal/StdioTransport.ts\"\nimport * as Transport from \"./internal/Transport.ts\"\nimport { McpError } from \"./McpError.ts\"\n\n/**\n * One remote tool as the server describes it.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface ToolDescription {\n readonly name: string\n readonly description: string | undefined\n /** The tool's parameter shape, as a JSON Schema document with `type: \"object\"`. */\n readonly inputSchema: Record<string, unknown>\n /** The tool's structured result shape, when the server disclosed one. */\n readonly outputSchema: Record<string, unknown> | undefined\n}\n\n/**\n * The result of one `tools/call`.\n *\n * MCP tool content is a small union (text, image, embedded resource, \u2026); this\n * client passes every block through by shape rather than modeling the union,\n * since {@link McpFlows} only needs to hand the blocks back to the caller.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface ToolResult {\n readonly content: ReadonlyArray<Record<string, unknown>>\n readonly isError: boolean\n readonly structuredContent: Record<string, unknown> | undefined\n}\n\n/**\n * A live MCP session, holding the tool catalog fetched at connect time and a\n * way to call one of its entries.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface McpClient {\n readonly server: string\n readonly tools: ReadonlyArray<ToolDescription>\n /**\n * Calls one catalogued tool. An unknown name fails with `tool_not_found`\n * before a JSON-RPC frame is written. Declared structured output is checked\n * against the supported output-schema subset before it is returned.\n */\n readonly callTool: (name: string, args: Record<string, unknown>) => Effect.Effect<ToolResult, McpError>\n}\n\n/**\n * Session and catalog limits shared by every transport.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface ClientOptions {\n /** The name this server is known by, for flow naming and error messages. */\n readonly server: string\n /** Deadline for each initialize/catalog request. See {@link defaultHandshakeTimeoutMs}. */\n readonly handshakeTimeoutMs?: number | undefined\n /** Maximum tools accepted across every catalog page. See {@link defaultMaxTools}. */\n readonly maxTools?: number | undefined\n /**\n * Maximum UTF-8 bytes in a tool name. Names also cannot be `.` or `..`, or\n * contain `/`, a control or format character (Unicode categories Cc and Cf,\n * which include bidi and zero-width marks), U+2028, U+2029, or a lone\n * surrogate. See {@link defaultMaxToolNameBytes}.\n */\n readonly maxToolNameBytes?: number | undefined\n /**\n * Maximum UTF-8 bytes of one tool's model-facing text: its description plus\n * its JSON-encoded `inputSchema`. See {@link defaultMaxToolDocumentBytes}.\n */\n readonly maxToolDocumentBytes?: number | undefined\n /** Maximum pages walked while fetching the catalog. See {@link defaultMaxCatalogPages}. */\n readonly maxCatalogPages?: number | undefined\n}\n\n/**\n * A server spawned as a child process and spoken to over its stdio.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface StdioConnectOptions extends StdioTransport.ConnectOptions, ClientOptions {\n readonly url?: never\n}\n\n/**\n * Supplies the bearer credential for a Streamable HTTP server. `token` runs\n * once per HTTP message, so a provider can rotate the credential; its failure\n * fails that message unchanged.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport type AuthProvider = HttpTransport.AuthProvider\n\n/**\n * A remote server reached over MCP Streamable HTTP through the `HttpClient`\n * in context.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface HttpConnectOptions extends HttpTransport.ConnectOptions, ClientOptions {\n readonly command?: never\n}\n\n/**\n * Options accepted by {@link connect}: a stdio command or an HTTP `url`.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type ConnectOptions = StdioConnectOptions | HttpConnectOptions\n\n/**\n * The services {@link connect} needs for the given options: a process spawner\n * for stdio, an `HttpClient` for a `url`.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport type Requirements<O extends ConnectOptions> = O extends { readonly url: string } ? HttpClient.HttpClient\n : ChildProcessSpawner\n\nconst isHttp = (options: ConnectOptions): options is HttpConnectOptions => options.url !== undefined\n\nconst PositiveInteger = Schema.Int.check(Schema.isGreaterThan(0))\n\n/**\n * Authoritative decoder for a persisted stdio MCP server entry.\n *\n * The schema requires non-empty server and command names, string arguments,\n * a plain string-valued environment record, and positive-integer limits.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const ConnectOptionsSchema = Schema.Struct({\n server: Schema.NonEmptyString,\n command: Schema.NonEmptyString,\n args: Schema.Array(Schema.String),\n cwd: Schema.optional(Schema.NonEmptyString),\n env: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n handshakeTimeoutMs: Schema.optional(PositiveInteger),\n requestTimeoutMs: Schema.optional(PositiveInteger),\n queueCapacity: Schema.optional(PositiveInteger),\n maxFrameBytes: Schema.optional(PositiveInteger),\n maxOutboundFrameBytes: Schema.optional(PositiveInteger),\n maxStderrBytes: Schema.optional(PositiveInteger),\n maxTools: Schema.optional(PositiveInteger),\n maxToolNameBytes: Schema.optional(PositiveInteger),\n maxToolDocumentBytes: Schema.optional(PositiveInteger),\n maxCatalogPages: Schema.optional(PositiveInteger)\n})\n\n/** An absolute `http:` or `https:` URL without credentials: userinfo would put a secret in the file. */\nconst isEndpoint = (url: string): boolean => {\n if (!URL.canParse(url)) return false\n const parsed = new URL(url)\n return (parsed.protocol === \"http:\" || parsed.protocol === \"https:\") && parsed.username === \"\" &&\n parsed.password === \"\"\n}\n\n/**\n * Authoritative decoder for a persisted Streamable HTTP MCP server entry.\n *\n * The schema requires a non-empty server name, an absolute `http:` or\n * `https:` `url` without userinfo, and positive-integer limits. A bearer\n * credential is never stored in the entry: `bearerTokenEnv` names the\n * environment variable the host reads it from and turns into an\n * {@link AuthProvider}.\n *\n * @category schemas\n * @since 1.0.0-rc.1\n */\nexport const HttpConnectOptionsSchema = Schema.Struct({\n server: Schema.NonEmptyString,\n url: Schema.String.check(Schema.makeFilter(isEndpoint, { expected: \"an http: or https: URL without credentials\" })),\n bearerTokenEnv: Schema.optionalKey(Schema.String.check(Schema.isPattern(/^[A-Za-z_][A-Za-z0-9_]*$/))),\n handshakeTimeoutMs: Schema.optional(PositiveInteger),\n requestTimeoutMs: Schema.optional(PositiveInteger),\n maxFrameBytes: Schema.optional(PositiveInteger),\n maxOutboundFrameBytes: Schema.optional(PositiveInteger),\n maxTools: Schema.optional(PositiveInteger),\n maxToolNameBytes: Schema.optional(PositiveInteger),\n maxToolDocumentBytes: Schema.optional(PositiveInteger),\n maxCatalogPages: Schema.optional(PositiveInteger)\n})\n\n/**\n * Frozen identity disclosed to every MCP server during initialization.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const clientInfo: { readonly name: string; readonly version: string } = Object.freeze({\n name: \"smithers\",\n version: \"1.0.0-rc.4\"\n})\n\n/**\n * MCP revisions whose `tools/list` and `tools/call` shapes this client\n * decodes. The frozen list always proposes `2025-06-18` first.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const supportedProtocolVersions: ReadonlyArray<string> = Object.freeze([\n \"2025-06-18\",\n \"2025-03-26\",\n \"2024-11-05\"\n])\n\n/**\n * Default deadline for each MCP handshake request.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultHandshakeTimeoutMs = 10_000\n\n/**\n * Default deadline for each tool request.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultRequestTimeoutMs = Transport.defaultRequestTimeoutMs\n\n/**\n * Default number of outbound frames allowed to wait in memory.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultQueueCapacity = StdioTransport.defaultQueueCapacity\n\n/**\n * Default maximum inbound JSON-RPC frame size.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxFrameBytes = Transport.defaultMaxFrameBytes\n\n/**\n * Default maximum outbound JSON-RPC frame size.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxOutboundFrameBytes = Transport.defaultMaxOutboundFrameBytes\n\n/**\n * Default maximum child-stderr tail retained for connection diagnostics.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxStderrBytes = StdioTransport.defaultMaxStderrBytes\n\n/**\n * Default maximum number of tools in a remote catalog.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxTools = 256\n\n/**\n * Default maximum UTF-8 byte length of one remote tool name.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxToolNameBytes = 128\n\n/**\n * Default maximum UTF-8 bytes of one tool's description plus its JSON-encoded\n * `inputSchema`, the server-authored text a model reads for that tool.\n *\n * @category constants\n * @since 1.0.0-rc.1\n */\nexport const defaultMaxToolDocumentBytes = 65_536\n\n/**\n * Default maximum number of remote catalog pages.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxCatalogPages = 32\n\n/**\n * Maximum nested JSON containers, including the JSON-RPC envelope. Fixed so\n * accepted server schemas and values remain safe for recursive consumers.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const maxJsonDepth = JsonLimits.maxDepth\n\nconst invalidResponse = (server: string, message: string): McpError =>\n new McpError({ code: \"invalid_response\", message, server })\n\nconst asInitialize = (server: string, result: unknown): Result.Result<void, McpError> => {\n if (!isRecord(result)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: result is not an object`\n ))\n }\n if (typeof result.protocolVersion !== \"string\") {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: protocolVersion is not a string`\n ))\n }\n if (!supportedProtocolVersions.includes(result.protocolVersion)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" speaks an unsupported protocol version; this client speaks ${\n supportedProtocolVersions.join(\", \")\n }`\n ))\n }\n if (!isRecord(result.capabilities)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: capabilities is not an object`\n ))\n }\n if (!Object.hasOwn(result.capabilities, \"tools\") || !isRecord(result.capabilities.tools)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" does not serve tools: its initialize result declares no tools capability`\n ))\n }\n return Result.succeed(undefined)\n}\n\ntype CatalogLimits = {\n readonly maxTools: number\n readonly maxToolNameBytes: number\n readonly maxToolDocumentBytes: number\n}\n\ntype ToolPage = {\n readonly nextCursor: string | undefined\n}\n\nconst nameEncoder = new TextEncoder()\n\n// Cc covers C0, DEL, and C1. Cf covers bidi overrides and isolates (U+202A-202E,\n// U+2066-2069), zero-width marks (U+200B-200F, U+2060, U+FEFF), and soft hyphen:\n// all invisible text that makes `mcp/<server>/<tool>` read as another tool.\n// Cs catches a lone surrogate, which UTF-8 encoding would silently replace.\nconst forbiddenToolNameCharacter = /[/\\p{Cc}\\p{Cf}\\p{Cs}\\u2028\\u2029]/u\n\nconst isForbiddenToolName = (name: string): boolean =>\n name === \".\" || name === \"..\" || forbiddenToolNameCharacter.test(name)\n\nconst asToolPage = (\n server: string,\n result: unknown,\n limits: CatalogLimits,\n seen: Set<string>,\n described: Array<ToolDescription>\n): Result.Result<ToolPage, McpError> => {\n const tools = isRecord(result) ? result.tools : undefined\n if (!Array.isArray(tools)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/list result with no tools array`\n ))\n }\n for (const [index, tool] of tools.entries()) {\n if (described.length >= limits.maxTools) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned more than ${limits.maxTools} tools`\n ))\n }\n if (!isRecord(tool)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned tools[${index}], which is not an object`\n ))\n }\n const record = tool\n if (typeof record.name !== \"string\" || record.name === \"\") {\n return Result.fail(invalidResponse(server, `MCP server \"${server}\" returned tools[${index}] with no name`))\n }\n if (nameEncoder.encode(record.name).byteLength > limits.maxToolNameBytes) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool name longer than ${limits.maxToolNameBytes} bytes`\n ))\n }\n if (isForbiddenToolName(record.name)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool name that is \".\" or \"..\", or contains \"/\" or an invisible or control character`\n ))\n }\n if (seen.has(record.name)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a duplicate tool name at catalog index ${index}`\n ))\n }\n if (!isRecord(record.inputSchema) || record.inputSchema.type !== \"object\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool whose inputSchema is not a JSON Schema object of type \"object\"`\n ))\n }\n const description = typeof record.description === \"string\" ? record.description : undefined\n const documentBytes = nameEncoder.encode(description ?? \"\").byteLength +\n nameEncoder.encode(JSON.stringify(record.inputSchema)).byteLength\n if (documentBytes > limits.maxToolDocumentBytes) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool description and inputSchema longer than ${limits.maxToolDocumentBytes} bytes`\n ))\n }\n let outputSchema: Record<string, unknown> | undefined\n if (Object.hasOwn(record, \"outputSchema\")) {\n if (!isRecord(record.outputSchema)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool whose outputSchema is not a JSON object`\n ))\n }\n outputSchema = record.outputSchema\n }\n seen.add(record.name)\n described.push({\n name: record.name,\n description,\n inputSchema: record.inputSchema,\n outputSchema\n })\n }\n\n const nextCursor = isRecord(result) && Object.hasOwn(result, \"nextCursor\") ? result.nextCursor : undefined\n if (nextCursor === undefined) return Result.succeed({ nextCursor: undefined })\n if (typeof nextCursor !== \"string\" || nextCursor === \"\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/list cursor that is not a non-empty string`\n ))\n }\n return Result.succeed({ nextCursor })\n}\n\n// Container guards deliberately inspect only the shape; traversal below owns\n// cooperative interruption. Schema.Int excludes unsafe integers, unlike JSON Schema.\nconst outputTypes = {\n null: Schema.Null,\n boolean: Schema.Boolean,\n object: Schema.declare(isRecord),\n array: Schema.declare(Array.isArray),\n number: Schema.Number,\n string: Schema.String,\n integer: Schema.Number.check(Schema.makeFilter(Number.isInteger))\n}\n\n// Every traversal step consumes a slice slot, including enum-key construction.\n// Yielding keeps validation interruptible after the transport has completed.\nconst runJsonWork = <A>(work: Generator<void, A>): Effect.Effect<A> =>\n Effect.gen(function*() {\n while (true) {\n for (let steps = 0; steps < 1_024; steps += 1) {\n const next = work.next()\n if (next.done) return next.value\n }\n yield* Effect.yieldNow\n }\n })\n\n// Keys are canonical JSON: object order is irrelevant, array order is not.\n// Inputs here are depth-checked parsed JSON, never caller-owned arguments.\nconst enumKey = function*(value: unknown): Generator<void, string> {\n yield\n if (Array.isArray(value)) {\n const items: Array<string> = []\n for (const item of value) items.push(yield* enumKey(item))\n return `[${items.join(\",\")}]`\n }\n if (isRecord(value)) {\n const members: Array<string> = []\n for (const key of Object.keys(value).sort()) {\n members.push(`${JSON.stringify(key)}:${yield* enumKey(value[key])}`)\n }\n return `{${members.join(\",\")}}`\n }\n return JSON.stringify(value)\n}\n\ntype OutputValidator = (value: unknown, path: string) => Generator<void, JsonIssue | undefined>\n\n/**\n * Compile the supported output-schema subset once per catalog. Effect Schema\n * owns type unions; this cooperative compatibility traversal retains composite\n * enums, own-property requirements and ignored unsupported keywords. Importing\n * the whole document would enforce constraints this client does not support.\n */\nconst compileOutputSchema = function*(schema: Record<string, unknown>): Generator<void, OutputValidator> {\n yield\n const types = new Set<keyof typeof outputTypes>()\n for (const candidate of Array.isArray(schema.type) ? schema.type : [schema.type]) {\n yield\n if (typeof candidate === \"string\" && Object.hasOwn(outputTypes, candidate)) {\n types.add(candidate as keyof typeof outputTypes)\n }\n }\n const accepts = Schema.is(\n types.size === 0 ? Schema.Unknown : Schema.Union([...types].map((type) => outputTypes[type]))\n )\n const typeReason = `expected ${[...types].join(\" or \")}`\n let enumIndex: Set<string> | undefined\n if (Array.isArray(schema.enum)) {\n enumIndex = new Set()\n for (const member of schema.enum) enumIndex.add(yield* enumKey(member))\n }\n const required: Array<string> = []\n if (Array.isArray(schema.required)) {\n for (const key of schema.required) {\n yield\n if (typeof key === \"string\") required.push(key)\n }\n }\n const properties: Array<readonly [string, OutputValidator]> = []\n if (isRecord(schema.properties)) {\n for (const [key, property] of Object.entries(schema.properties)) {\n yield\n if (isRecord(property)) properties.push([key, yield* compileOutputSchema(property)])\n }\n }\n const items = isRecord(schema.items) ? yield* compileOutputSchema(schema.items) : undefined\n\n return function*(value, path) {\n yield\n if (enumIndex !== undefined && !enumIndex.has(yield* enumKey(value))) {\n return { path, reason: \"expected a declared enum value\" }\n }\n if (!accepts(value)) return { path, reason: typeReason }\n if (isRecord(value)) {\n for (const key of required) {\n yield\n if (!Object.hasOwn(value, key)) return { path: `${path}.${key}`, reason: \"required property is missing\" }\n }\n for (const [key, validate] of properties) {\n yield\n if (!Object.hasOwn(value, key)) continue\n const issue = yield* validate(value[key], `${path}.${key}`)\n if (issue !== undefined) return issue\n }\n }\n if (Array.isArray(value) && items !== undefined) {\n for (const [index, item] of value.entries()) {\n const issue = yield* items(item, `${path}[${index}]`)\n if (issue !== undefined) return issue\n }\n }\n return undefined\n }\n}\n\nconst asToolResult = function*(\n server: string,\n result: unknown,\n outputSchema: Record<string, unknown> | undefined,\n diagnostic: (source: \"invalid-response\", detail: unknown) => void,\n validate: OutputValidator | undefined\n): Generator<void, Result.Result<ToolResult, McpError>> {\n if (!isRecord(result)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result that is not an object`\n ))\n }\n const hasContent = Object.hasOwn(result, \"content\")\n const hasStructuredContent = Object.hasOwn(result, \"structuredContent\")\n if (!hasContent && !hasStructuredContent) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result with no content array`\n ))\n }\n if (hasContent && !Array.isArray(result.content)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result with no content array`\n ))\n }\n const content: Array<Record<string, unknown>> = []\n const blocks = hasContent ? result.content as Array<unknown> : []\n for (const [index, block] of blocks.entries()) {\n yield\n if (!isRecord(block)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose content[${index}] is not an object`\n ))\n }\n content.push(block)\n }\n if (Object.hasOwn(result, \"isError\") && typeof result.isError !== \"boolean\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose isError is not a boolean`\n ))\n }\n let structuredContent: Record<string, unknown> | undefined\n if (hasStructuredContent) {\n if (!isRecord(result.structuredContent)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose structuredContent is not a JSON object`\n ))\n }\n structuredContent = result.structuredContent\n if (validate !== undefined) {\n const issue = yield* validate(structuredContent, \"structuredContent\")\n if (issue !== undefined) {\n diagnostic(\"invalid-response\", { issue, outputSchema })\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned structuredContent that its own outputSchema rejects: ${issue.reason}; property path withheld`\n ))\n }\n }\n }\n return Result.succeed({\n content,\n isError: result.isError === true,\n structuredContent\n })\n}\n\ninterface JsonObject {\n [key: string]: JsonValue\n}\n\ntype JsonValue = null | boolean | number | string | Array<JsonValue> | JsonObject\n\ntype JsonIssue = {\n readonly path: string\n readonly reason: string\n}\n\ntype JsonPath = string | { readonly parent: JsonPath; key: string | number }\n\nconst renderJsonPath = (path: JsonPath): string =>\n typeof path === \"string\" ?\n path :\n `${renderJsonPath(path.parent)}${typeof path.key === \"number\" ? `[${path.key}]` : `.${path.key}`}`\n\nconst jsonFailure = (path: JsonPath, reason: string): Result.Result<JsonValue, JsonIssue> =>\n Result.fail({ path: renderJsonPath(path), reason })\n\nconst reflect = <A>(thunk: () => A): Result.Result<A, string> => {\n try {\n return Result.succeed(thunk())\n } catch {\n return Result.fail(\"a property that threw when read\")\n }\n}\n\nconst ownDescriptors = (object: object): Result.Result<PropertyDescriptorMap, string> =>\n reflect(() => Object.getOwnPropertyDescriptors(object))\n\nconst isAccessor = (descriptor: PropertyDescriptor): boolean =>\n Object.hasOwn(descriptor, \"get\") || Object.hasOwn(descriptor, \"set\")\n\ntype JsonBudget = { remaining: number }\n\n// Lower bounds on encoded size avoid expanding repeated references into an\n// enormous tree before the transport's exact UTF-8 frame check. String/key\n// UTF-16 length is a lower bound even with escapes and surrogate pairs.\nconst spendJson = (budget: JsonBudget, bytes: number): boolean => {\n budget.remaining -= bytes\n return budget.remaining >= 0\n}\n\nconst snapshotJson = (\n value: unknown,\n path: JsonPath,\n ancestors: Set<object>,\n budget: JsonBudget\n): Result.Result<JsonValue, JsonIssue> => {\n const bytes = typeof value === \"string\" ?\n value.length + 2\n : typeof value === \"number\" || typeof value === \"boolean\" ?\n String(value).length\n : value === null ?\n 4\n : 2\n if (!spendJson(budget, bytes)) return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n if (value === null) return Result.succeed(null)\n if (typeof value === \"boolean\" || typeof value === \"string\") return Result.succeed(value)\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? Result.succeed(value) : jsonFailure(path, \"a non-finite number\")\n }\n if (typeof value === \"undefined\") return jsonFailure(path, \"undefined\")\n if (typeof value === \"bigint\") return jsonFailure(path, \"a bigint\")\n if (typeof value === \"function\") return jsonFailure(path, \"a function\")\n if (typeof value === \"symbol\") return jsonFailure(path, \"a symbol\")\n\n if (ancestors.has(value)) return jsonFailure(path, \"a cyclic reference\")\n // Arguments live inside the wire envelope and its params object.\n if (ancestors.size + 3 > maxJsonDepth) return jsonFailure(path, `JSON nesting exceeds ${maxJsonDepth} containers`)\n const array = reflect(() => Array.isArray(value))\n if (Result.isFailure(array)) return jsonFailure(path, array.failure)\n if (array.success) {\n const length = reflect(() => (value as Array<unknown>).length)\n if (Result.isFailure(length)) return jsonFailure(path, length.failure)\n if (!Number.isSafeInteger(length.success) || length.success < 0) {\n return jsonFailure(path, \"a property that threw when read\")\n }\n if (!spendJson(budget, Math.max(0, length.success - 1))) {\n return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n }\n const descriptors = ownDescriptors(value)\n if (Result.isFailure(descriptors)) return jsonFailure(path, descriptors.failure)\n ancestors.add(value)\n const copied: Array<JsonValue> = []\n const memberPath: JsonPath = { parent: path, key: 0 }\n for (let index = 0; index < length.success; index += 1) {\n memberPath.key = index\n // Missing slots must not resolve through Object.prototype.\n const descriptor = Object.hasOwn(descriptors.success, index) ? descriptors.success[index] : undefined\n if (descriptor !== undefined && isAccessor(descriptor)) {\n ancestors.delete(value)\n return jsonFailure(memberPath, \"an accessor property\")\n }\n const member = descriptor === undefined ? undefined : descriptor.value\n const snapshot = snapshotJson(member, memberPath, ancestors, budget)\n if (Result.isFailure(snapshot)) {\n ancestors.delete(value)\n return snapshot\n }\n copied.push(snapshot.success)\n }\n ancestors.delete(value)\n return Result.succeed(copied)\n }\n\n const object = value as Record<string, unknown>\n const prototype = reflect(() => Object.getPrototypeOf(object))\n if (Result.isFailure(prototype)) return jsonFailure(path, prototype.failure)\n if (prototype.success !== Object.prototype && prototype.success !== null) {\n return jsonFailure(path, \"an object with a non-plain prototype\")\n }\n const symbols = reflect(() => Object.getOwnPropertySymbols(object))\n if (Result.isFailure(symbols)) return jsonFailure(path, symbols.failure)\n const descriptors = ownDescriptors(object)\n if (Result.isFailure(descriptors)) return jsonFailure(path, descriptors.failure)\n for (const key of symbols.success) {\n if (Object.hasOwn(descriptors.success, key) && descriptors.success[key]!.enumerable) {\n return jsonFailure(path, \"a symbol-keyed property\")\n }\n }\n\n ancestors.add(object)\n const copied: JsonObject = {}\n let members = 0\n const memberPath: JsonPath = { parent: path, key: \"\" }\n for (const key of Object.keys(descriptors.success)) {\n memberPath.key = key\n const descriptor = descriptors.success[key]!\n if (descriptor.enumerable !== true) continue\n if (!spendJson(budget, key.length + 3 + Math.min(1, members++))) {\n ancestors.delete(object)\n return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n }\n if (isAccessor(descriptor)) {\n ancestors.delete(object)\n return jsonFailure(memberPath, \"an accessor property\")\n }\n const snapshot = snapshotJson(descriptor.value, memberPath, ancestors, budget)\n if (Result.isFailure(snapshot)) {\n ancestors.delete(object)\n return snapshot\n }\n Object.defineProperty(copied, key, {\n configurable: true,\n enumerable: true,\n value: snapshot.success,\n writable: true\n })\n }\n ancestors.delete(object)\n return Result.succeed(copied)\n}\n\nconst snapshotArguments = (\n server: string,\n args: Record<string, unknown>,\n diagnostic: (source: \"invalid-arguments\", detail: unknown) => void,\n maxBytes: number\n): Result.Result<Record<string, unknown>, McpError> => {\n const snapshot = snapshotJson(args, \"arguments\", new Set(), { remaining: maxBytes })\n if (Result.isFailure(snapshot)) {\n diagnostic(\"invalid-arguments\", snapshot.failure)\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" was sent a tool argument that is not JSON: ${snapshot.failure.reason}; property path withheld`\n ))\n }\n if (!isRecord(snapshot.success)) {\n return Result.fail(Limits.protocolError(server, `MCP server \"${server}\" tool arguments must be a JSON object`))\n }\n return Result.succeed(snapshot.success)\n}\n\n/**\n * Connects to an MCP server over stdio (`command`) or Streamable HTTP (`url`),\n * completes the `initialize` handshake, and fetches its tool catalog once, up\n * front. Failed or interrupted setup closes its subprocess, I/O fibers, or\n * HTTP session before returning to the caller; a successful session stays\n * open until the caller scope closes.\n *\n * The tool catalog is a snapshot: a server that changes its tools after\n * connecting (a `notifications/tools/list_changed` push) is not re-polled.\n * {@link McpFlows} rebuilds by reconnecting to refresh.\n * Catalog input schemas must declare `type: \"object\"`. A later tool result may\n * omit `content` when it carries `structuredContent`; a declared output schema\n * is enforced for the documented keyword subset.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const connect = <O extends ConnectOptions>(\n options: O\n): Effect.Effect<McpClient, McpError, Requirements<O> | Scope.Scope> =>\n Effect.acquireUseRelease(\n Effect.flatMap(Effect.scope, Scope.fork),\n (scope) =>\n Effect.gen(function*() {\n const diagnostic = yield* DiagnosticReporter.make(options.server)\n const decodeResponse = <A>(response: unknown, decoded: Result.Result<A, McpError>) =>\n Effect.fromResult(decoded).pipe(\n Effect.tapError(() => Effect.sync(() => diagnostic(\"invalid-response\", response)))\n )\n const handshakeTimeoutMs = options.handshakeTimeoutMs ?? defaultHandshakeTimeoutMs\n const maxArgumentBytes = options.maxOutboundFrameBytes ?? defaultMaxOutboundFrameBytes\n const maxTools = options.maxTools ?? defaultMaxTools\n const maxToolNameBytes = options.maxToolNameBytes ?? defaultMaxToolNameBytes\n const maxToolDocumentBytes = options.maxToolDocumentBytes ?? defaultMaxToolDocumentBytes\n const maxCatalogPages = options.maxCatalogPages ?? defaultMaxCatalogPages\n yield* Limits.checkPositiveIntegers(options.server, [\n [\"handshakeTimeoutMs\", handshakeTimeoutMs],\n [\"maxTools\", maxTools],\n [\"maxToolNameBytes\", maxToolNameBytes],\n [\"maxToolDocumentBytes\", maxToolDocumentBytes],\n [\"maxCatalogPages\", maxCatalogPages]\n ])\n\n const transport: Transport.Transport = yield* (isHttp(options)\n ? HttpTransport.connect(options)\n : StdioTransport.connect(options))\n\n const initialized = yield* transport.request(\n \"initialize\",\n {\n protocolVersion: supportedProtocolVersions[0],\n capabilities: {},\n clientInfo\n },\n handshakeTimeoutMs\n )\n yield* decodeResponse(initialized, asInitialize(options.server, initialized))\n // A notification, not a request: the server never replies to it, and the\n // handshake is not complete until the client sends it.\n yield* transport.notify(\"notifications/initialized\", undefined, handshakeTimeoutMs)\n\n const tools: Array<ToolDescription> = []\n const toolNames = new Set<string>()\n const cursors = new Set<string>()\n let params: Record<string, unknown> = {}\n let pageCount = 0\n while (true) {\n const listed = yield* transport.request(\"tools/list\", params, handshakeTimeoutMs)\n pageCount += 1\n const page = yield* decodeResponse(\n listed,\n asToolPage(\n options.server,\n listed,\n { maxTools, maxToolNameBytes, maxToolDocumentBytes },\n toolNames,\n tools\n )\n )\n if (page.nextCursor === undefined) break\n if (cursors.has(page.nextCursor)) {\n diagnostic(\"invalid-response\", listed)\n return yield* Effect.fail(invalidResponse(\n options.server,\n `MCP server \"${options.server}\" repeated a tools/list cursor`\n ))\n }\n if (pageCount >= maxCatalogPages) {\n return yield* Effect.fail(invalidResponse(\n options.server,\n `MCP server \"${options.server}\" returned more than ${maxCatalogPages} tools/list pages`\n ))\n }\n cursors.add(page.nextCursor)\n params = { cursor: page.nextCursor }\n }\n JsonLimits.freezeParsed(tools)\n const validators = new Map<string, OutputValidator>()\n for (const tool of tools) {\n if (tool.outputSchema !== undefined) {\n validators.set(tool.name, yield* runJsonWork(compileOutputSchema(tool.outputSchema)))\n }\n }\n\n const callTool = (name: string, args: Record<string, unknown>): Effect.Effect<ToolResult, McpError> => {\n const tool = tools.find((candidate) => candidate.name === name)\n if (tool === undefined) {\n return Effect.fail(\n new McpError({\n code: \"tool_not_found\",\n message: `MCP server \"${options.server}\" has no requested tool`,\n server: options.server\n })\n )\n }\n const snapshot = snapshotArguments(options.server, args, diagnostic, maxArgumentBytes)\n if (Result.isFailure(snapshot)) {\n // Do not inspect the rejected object again: it may contain throwing\n // accessors or proxies. Even diagnostic observers see only the safe\n // rejection, never a second traversal of executable user properties.\n return Effect.fail(snapshot.failure)\n }\n return Effect.flatMap(\n transport.request(\"tools/call\", { name, arguments: snapshot.success }),\n (result) =>\n Effect.flatMap(\n runJsonWork(asToolResult(options.server, result, tool.outputSchema, diagnostic, validators.get(name))),\n (decoded) => decodeResponse(result, decoded)\n )\n )\n }\n\n return { server: options.server, tools, callTool }\n }).pipe(Scope.provide(scope)),\n // Closing a failed attempt also detaches it from the caller's scope.\n // Successful sessions remain owned by that scope until it closes.\n (scope, exit) => Exit.isFailure(exit) ? Scope.close(scope, exit) : Effect.void\n ) as Effect.Effect<McpClient, McpError, Requirements<O> | Scope.Scope>\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["descriptors", "copied", "memberPath"]
|
|
7
7
|
}
|
package/dist/cjs/McpFlows.d.ts
CHANGED
|
@@ -51,8 +51,9 @@ export declare const Result: Schema.Struct<{
|
|
|
51
51
|
* rejects anything that does not have exactly those three colon-separated
|
|
52
52
|
* components. An unparseable declaration counts as unauthorized. The list is
|
|
53
53
|
* derived from `Capability.Action.literals`, so adding a host action cannot
|
|
54
|
-
* silently omit it from MCP tools, and it is frozen
|
|
55
|
-
*
|
|
54
|
+
* silently omit it from MCP tools, and it is frozen so no caller can narrow
|
|
55
|
+
* or widen what every tool declares. Each binding records it deduplicated and
|
|
56
|
+
* sorted, as `FlowBinding.make` records every declaration.
|
|
56
57
|
*
|
|
57
58
|
* @category constants
|
|
58
59
|
* @since 1.0.0-rc.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpFlows.d.ts","sourceRoot":"","sources":["../../src/McpFlows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAA;AAC/C,OAAO,KAAK,WAAW,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,MAAM,EAAQ,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACpD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,+CAA+C,CAAA;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,MAAM;;;;EAIjB,CAAA;AAEF
|
|
1
|
+
{"version":3,"file":"McpFlows.d.ts","sourceRoot":"","sources":["../../src/McpFlows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAA;AAC/C,OAAO,KAAK,WAAW,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,MAAM,EAAQ,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACpD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,+CAA+C,CAAA;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,MAAM;;;;EAIjB,CAAA;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC,MAAM,CAE9C,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,OAAO,qBAMlB,CAAA;AAEF;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;IACpD,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;IACpD,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACzC;AAwCD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,GAAG,GAAI,QAAQ,SAAS,CAAC,SAAS,EAAE,UAAS,iBAAsB,KAAG,WAAW,CAAC,MAU9F,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,SAAS,CAAC,cAAc,EAC1D,SAAS,CAAC,GAAG,iBAAiB,KAC7B,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAgClF,CAAA"}
|
package/dist/cjs/McpFlows.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/McpFlows.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Projects a connected MCP server's tools as an ordinary {@link FlowBinding.Source}.\n *\n * This is the whole adapter: `@smthrs/harness/FlowBinding`'s own module doc\n * already names the target directly: \"a standard filesystem flow, a memory\n * flow, an incoming MCP tool, a durable child agent\" are all just a flow\n * declaration plus the code that runs it. Nothing about the harness, the\n * registry, or the cell loop needs to know a given flow's implementation\n * happens to proxy a remote MCP `tools/call`; a cell that reads a file and a\n * cell that calls an MCP tool run the identical two lines.\n *\n * @since 1.0.0-rc.0\n */\n\nimport * as Capability from \"@smthrs/capability/Capability\"\nimport * as Effects from \"@smthrs/core/Effects\"\nimport * as FlowBinding from \"@smthrs/harness/FlowBinding\"\nimport { Effect, Exit, Schema, Scope } from \"effect\"\nimport * as McpClient from \"./McpClient.ts\"\nimport { McpError } from \"./McpError.ts\"\n\n/**\n * Decoded input accepted by every MCP tool flow, which is whatever the remote\n * tool's own JSON Schema describes. The registry still discloses the real parameter\n * shape, as shown by {@link toolBinding}. This is only the runtime decode, and it\n * is permissive because the server, not this adapter, owns validation.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Args = Schema.Record(Schema.String, Schema.Unknown)\n\n/**\n * Decoded output returned by every MCP tool flow, carrying the tool's content\n * blocks by shape plus whether the server reported an error.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Result = Schema.Struct({\n content: Schema.Array(Schema.Record(Schema.String, Schema.Unknown)),\n isError: Schema.Boolean,\n structuredContent: Schema.optional(Schema.Record(Schema.String, Schema.Unknown))\n})\n\n/**\n * The authority every MCP tool flow declares.\n *\n * An MCP tool is opaque code this adapter does not control, the same\n * situation `@smthrs/registry/MarkdownFlow` calls \"unprojectable authority\"\n * for a skill with no declared `capabilities`: the honest declaration is\n * everything, not a guess.\n *\n * It is spelled as one exact `namespace:operation:resource` per action because\n * the cell boundary reads each declaration with `Capability.parse`, which\n * rejects anything that does not have exactly those three colon-separated\n * components. An unparseable declaration counts as unauthorized. The list is\n * derived from `Capability.Action.literals`, so adding a host action cannot\n * silently omit it from MCP tools, and it is frozen
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,iBAA4B;AAC5B,cAAyB;AACzB,kBAA6B;AAC7B,oBAA4C;AAC5C,gBAA2B;AAC3B,sBAAyB;AAWlB,MAAM,OAAO,qBAAO,OAAO,qBAAO,QAAQ,qBAAO,OAAO;AASxD,MAAM,SAAS,qBAAO,OAAO;AAAA,EAClC,SAAS,qBAAO,MAAM,qBAAO,OAAO,qBAAO,QAAQ,qBAAO,OAAO,CAAC;AAAA,EAClE,SAAS,qBAAO;AAAA,EAChB,mBAAmB,qBAAO,SAAS,qBAAO,OAAO,qBAAO,QAAQ,qBAAO,OAAO,CAAC;AACjF,CAAC;
|
|
4
|
+
"sourcesContent": ["/**\n * Projects a connected MCP server's tools as an ordinary {@link FlowBinding.Source}.\n *\n * This is the whole adapter: `@smthrs/harness/FlowBinding`'s own module doc\n * already names the target directly: \"a standard filesystem flow, a memory\n * flow, an incoming MCP tool, a durable child agent\" are all just a flow\n * declaration plus the code that runs it. Nothing about the harness, the\n * registry, or the cell loop needs to know a given flow's implementation\n * happens to proxy a remote MCP `tools/call`; a cell that reads a file and a\n * cell that calls an MCP tool run the identical two lines.\n *\n * @since 1.0.0-rc.0\n */\n\nimport * as Capability from \"@smthrs/capability/Capability\"\nimport * as Effects from \"@smthrs/core/Effects\"\nimport * as FlowBinding from \"@smthrs/harness/FlowBinding\"\nimport { Effect, Exit, Schema, Scope } from \"effect\"\nimport * as McpClient from \"./McpClient.ts\"\nimport { McpError } from \"./McpError.ts\"\n\n/**\n * Decoded input accepted by every MCP tool flow, which is whatever the remote\n * tool's own JSON Schema describes. The registry still discloses the real parameter\n * shape, as shown by {@link toolBinding}. This is only the runtime decode, and it\n * is permissive because the server, not this adapter, owns validation.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Args = Schema.Record(Schema.String, Schema.Unknown)\n\n/**\n * Decoded output returned by every MCP tool flow, carrying the tool's content\n * blocks by shape plus whether the server reported an error.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Result = Schema.Struct({\n content: Schema.Array(Schema.Record(Schema.String, Schema.Unknown)),\n isError: Schema.Boolean,\n structuredContent: Schema.optional(Schema.Record(Schema.String, Schema.Unknown))\n})\n\n/**\n * The authority every MCP tool flow declares.\n *\n * An MCP tool is opaque code this adapter does not control, the same\n * situation `@smthrs/registry/MarkdownFlow` calls \"unprojectable authority\"\n * for a skill with no declared `capabilities`: the honest declaration is\n * everything, not a guess.\n *\n * It is spelled as one exact `namespace:operation:resource` per action because\n * the cell boundary reads each declaration with `Capability.parse`, which\n * rejects anything that does not have exactly those three colon-separated\n * components. An unparseable declaration counts as unauthorized. The list is\n * derived from `Capability.Action.literals`, so adding a host action cannot\n * silently omit it from MCP tools, and it is frozen so no caller can narrow\n * or widen what every tool declares. Each binding records it deduplicated and\n * sorted, as `FlowBinding.make` records every declaration.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const capabilities: ReadonlyArray<string> = Object.freeze(\n Capability.Action.literals.map((action) => `${action}:**`)\n)\n\n/**\n * The conservative effect envelope every MCP tool flow declares.\n *\n * @category effects\n * @since 1.0.0-rc.0\n */\nexport const effects = Effects.make({\n reads: [\"**\"],\n writes: [\"**\"],\n mode: \"expected\",\n onConflict: \"serialize\",\n tier: \"irreversible\"\n})\n\n/**\n * Selects and names the tools projected from one MCP catalog.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface ProjectionOptions {\n /** Exact tool names to project. Omitted or empty means every tool. */\n readonly include?: ReadonlyArray<string> | undefined\n /** Exact tool names to drop, applied after `include`. */\n readonly exclude?: ReadonlyArray<string> | undefined\n /** Replaces the default `mcp/<server>` flow-name prefix. */\n readonly namePrefix?: string | undefined\n}\n\n/** One remote tool, bound to a flow name scoped by server so two servers may reuse a tool name. */\nconst toolBinding = (\n client: McpClient.McpClient,\n tool: McpClient.ToolDescription,\n prefix: string\n): FlowBinding.Binding => {\n const toolName = tool.name\n return FlowBinding.make({\n flow: {\n name: `${prefix}/${toolName}`,\n // The server authors this text, so it is attributed as remote content\n // rather than read as if the host had written it. The client bounds it.\n description: tool.description === undefined\n ? `MCP tool \"${toolName}\" on server \"${client.server}\"`\n : `MCP tool \"${toolName}\" on server \"${client.server}\". Server-supplied description: ${tool.description}`,\n capabilities,\n effects,\n input: Args,\n output: Result\n },\n // The server's own JSON Schema document, carried by value so a caller\n // reading `ctx.flows` sees the real parameter shape rather than `Args`'s\n // permissive record type.\n inputDocument: tool.inputSchema as Schema.Json,\n // McpClient authors these messages with remote/process diagnostics withheld.\n publicError: (error: McpError) => error.message,\n handler: (input): Effect.Effect<typeof Result.Type, McpError> =>\n Effect.map(client.callTool(toolName, input), (result) =>\n result.structuredContent === undefined\n ? { content: result.content, isError: result.isError }\n : {\n content: result.content,\n isError: result.isError,\n structuredContent: result.structuredContent\n })\n })\n}\n\n/**\n * Projects an already-connected MCP session's tool catalog as a\n * {@link FlowBinding.Source}, one flow per tool.\n *\n * The client is a precondition, not a parameter this constructor resolves:\n * connecting is a scoped effect (it owns a subprocess), and a `Source` is not\n * scoped, so the host composes {@link McpClient.connect} once, at the same\n * place it composes every other scoped kernel service, and passes the live\n * client here.\n *\n * This constructor is total: it applies exact filters to the catalog it is\n * given. Use {@link connected} when unknown `include` names and an empty\n * `namePrefix` must fail loudly against a freshly fetched catalog.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const mcp = (client: McpClient.McpClient, options: ProjectionOptions = {}): FlowBinding.Source => {\n const prefix = options.namePrefix ?? `mcp/${client.server}`\n const include = options.include === undefined || options.include.length === 0\n ? undefined\n : new Set(options.include)\n const exclude = new Set(options.exclude ?? [])\n const tools = client.tools.filter((tool) =>\n (include === undefined || include.has(tool.name)) && !exclude.has(tool.name)\n )\n return FlowBinding.source(prefix, tools.map((tool) => toolBinding(client, tool, prefix)))\n}\n\n/**\n * Connects to an MCP server and projects its tools in one step.\n *\n * This is the checked entry point: it validates projection options against\n * the freshly fetched catalog before constructing the source. An empty prefix\n * fails before spawning. Failed or interrupted setup, including projection\n * validation, releases the connection before returning to the caller.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const connected = <O extends McpClient.ConnectOptions>(\n options: O & ProjectionOptions\n): Effect.Effect<FlowBinding.Source, McpError, McpClient.Requirements<O> | Scope.Scope> =>\n Effect.gen(function*() {\n if (options.namePrefix === \"\") {\n return yield* Effect.fail(\n new McpError({\n code: \"protocol_error\",\n message: `MCP server \"${options.server}\" option \"namePrefix\" must not be empty`,\n server: options.server\n })\n )\n }\n return yield* Effect.acquireUseRelease(\n Effect.flatMap(Effect.scope, Scope.fork),\n (scope) =>\n Effect.gen(function*() {\n const client = yield* McpClient.connect(options)\n const offered = new Set(client.tools.map((tool) => tool.name))\n const missing = options.include?.find((name) => !offered.has(name))\n if (missing !== undefined) {\n return yield* Effect.fail(\n new McpError({\n code: \"tool_not_found\",\n message: `MCP server \"${client.server}\" offers no requested include tool`,\n server: client.server\n })\n )\n }\n return mcp(client, options)\n }).pipe(Scope.provide(scope)),\n // Projection rejection must release the successfully initialized client.\n (scope, exit) => Exit.isFailure(exit) ? Scope.close(scope, exit) : Effect.void\n )\n })\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,iBAA4B;AAC5B,cAAyB;AACzB,kBAA6B;AAC7B,oBAA4C;AAC5C,gBAA2B;AAC3B,sBAAyB;AAWlB,MAAM,OAAO,qBAAO,OAAO,qBAAO,QAAQ,qBAAO,OAAO;AASxD,MAAM,SAAS,qBAAO,OAAO;AAAA,EAClC,SAAS,qBAAO,MAAM,qBAAO,OAAO,qBAAO,QAAQ,qBAAO,OAAO,CAAC;AAAA,EAClE,SAAS,qBAAO;AAAA,EAChB,mBAAmB,qBAAO,SAAS,qBAAO,OAAO,qBAAO,QAAQ,qBAAO,OAAO,CAAC;AACjF,CAAC;AAsBM,MAAM,eAAsC,OAAO;AAAA,EACxD,WAAW,OAAO,SAAS,IAAI,CAAC,WAAW,GAAG,MAAM,KAAK;AAC3D;AAQO,MAAM,UAAU,QAAQ,KAAK;AAAA,EAClC,OAAO,CAAC,IAAI;AAAA,EACZ,QAAQ,CAAC,IAAI;AAAA,EACb,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,MAAM;AACR,CAAC;AAkBD,MAAM,cAAc,CAClB,QACA,MACA,WACwB;AACxB,QAAM,WAAW,KAAK;AACtB,SAAO,YAAY,KAAK;AAAA,IACtB,MAAM;AAAA,MACJ,MAAM,GAAG,MAAM,IAAI,QAAQ;AAAA;AAAA;AAAA,MAG3B,aAAa,KAAK,gBAAgB,SAC9B,aAAa,QAAQ,gBAAgB,OAAO,MAAM,MAClD,aAAa,QAAQ,gBAAgB,OAAO,MAAM,mCAAmC,KAAK,WAAW;AAAA,MACzG;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,IACV;AAAA;AAAA;AAAA;AAAA,IAIA,eAAe,KAAK;AAAA;AAAA,IAEpB,aAAa,CAAC,UAAoB,MAAM;AAAA,IACxC,SAAS,CAAC,UACR,qBAAO,IAAI,OAAO,SAAS,UAAU,KAAK,GAAG,CAAC,WAC5C,OAAO,sBAAsB,SACzB,EAAE,SAAS,OAAO,SAAS,SAAS,OAAO,QAAQ,IACnD;AAAA,MACA,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,MAChB,mBAAmB,OAAO;AAAA,IAC5B,CAAC;AAAA,EACT,CAAC;AACH;AAmBO,MAAM,MAAM,CAAC,QAA6B,UAA6B,CAAC,MAA0B;AACvG,QAAM,SAAS,QAAQ,cAAc,OAAO,OAAO,MAAM;AACzD,QAAM,UAAU,QAAQ,YAAY,UAAa,QAAQ,QAAQ,WAAW,IACxE,SACA,IAAI,IAAI,QAAQ,OAAO;AAC3B,QAAM,UAAU,IAAI,IAAI,QAAQ,WAAW,CAAC,CAAC;AAC7C,QAAM,QAAQ,OAAO,MAAM;AAAA,IAAO,CAAC,UAChC,YAAY,UAAa,QAAQ,IAAI,KAAK,IAAI,MAAM,CAAC,QAAQ,IAAI,KAAK,IAAI;AAAA,EAC7E;AACA,SAAO,YAAY,OAAO,QAAQ,MAAM,IAAI,CAAC,SAAS,YAAY,QAAQ,MAAM,MAAM,CAAC,CAAC;AAC1F;AAaO,MAAM,YAAY,CACvB,YAEA,qBAAO,IAAI,aAAY;AACrB,MAAI,QAAQ,eAAe,IAAI;AAC7B,WAAO,OAAO,qBAAO;AAAA,MACnB,IAAI,yBAAS;AAAA,QACX,MAAM;AAAA,QACN,SAAS,eAAe,QAAQ,MAAM;AAAA,QACtC,QAAQ,QAAQ;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,OAAO,qBAAO;AAAA,IACnB,qBAAO,QAAQ,qBAAO,OAAO,oBAAM,IAAI;AAAA,IACvC,CAAC,UACC,qBAAO,IAAI,aAAY;AACrB,YAAM,SAAS,OAAO,UAAU,QAAQ,OAAO;AAC/C,YAAM,UAAU,IAAI,IAAI,OAAO,MAAM,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC;AAC7D,YAAM,UAAU,QAAQ,SAAS,KAAK,CAAC,SAAS,CAAC,QAAQ,IAAI,IAAI,CAAC;AAClE,UAAI,YAAY,QAAW;AACzB,eAAO,OAAO,qBAAO;AAAA,UACnB,IAAI,yBAAS;AAAA,YACX,MAAM;AAAA,YACN,SAAS,eAAe,OAAO,MAAM;AAAA,YACrC,QAAQ,OAAO;AAAA,UACjB,CAAC;AAAA,QACH;AAAA,MACF;AACA,aAAO,IAAI,QAAQ,OAAO;AAAA,IAC5B,CAAC,EAAE,KAAK,oBAAM,QAAQ,KAAK,CAAC;AAAA;AAAA,IAE9B,CAAC,OAAO,SAAS,mBAAK,UAAU,IAAI,IAAI,oBAAM,MAAM,OAAO,IAAI,IAAI,qBAAO;AAAA,EAC5E;AACF,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/McpClient.js
CHANGED
|
@@ -88,7 +88,7 @@ export const HttpConnectOptionsSchema = Schema.Struct({
|
|
|
88
88
|
*/
|
|
89
89
|
export const clientInfo = Object.freeze({
|
|
90
90
|
name: "smithers",
|
|
91
|
-
version: "1.0.0-rc.
|
|
91
|
+
version: "1.0.0-rc.4"
|
|
92
92
|
});
|
|
93
93
|
/**
|
|
94
94
|
* MCP revisions whose `tools/list` and `tools/call` shapes this client
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpClient.js","sourceRoot":"","sources":["../../src/McpClient.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A minimal MCP client covering the `initialize` handshake, `tools/list`, and\n * `tools/call`, over stdio or Streamable HTTP.\n *\n * This is deliberately not a general MCP SDK. Smithers has exactly one\n * consumer of an MCP session: {@link McpFlows}, which needs a tool catalog\n * and a way to invoke one entry from it, so the client exposes only that.\n * Resources, prompts, sampling, and roots are not wired up; add them here\n * when a flow adapter needs them, not speculatively.\n *\n * @since 1.0.0-rc.0\n */\n\nimport { isRecord } from \"@smthrs/canonical/Record\"\nimport { Effect, Exit, Result, Schema, Scope } from \"effect\"\nimport type * as HttpClient from \"effect/unstable/http/HttpClient\"\nimport type { ChildProcessSpawner } from \"effect/unstable/process/ChildProcessSpawner\"\nimport * as DiagnosticReporter from \"./internal/DiagnosticReporter.ts\"\nimport * as HttpTransport from \"./internal/HttpTransport.ts\"\nimport * as JsonLimits from \"./internal/JsonLimits.ts\"\nimport * as Limits from \"./internal/Limits.ts\"\nimport * as StdioTransport from \"./internal/StdioTransport.ts\"\nimport * as Transport from \"./internal/Transport.ts\"\nimport { McpError } from \"./McpError.ts\"\n\n/**\n * One remote tool as the server describes it.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface ToolDescription {\n readonly name: string\n readonly description: string | undefined\n /** The tool's parameter shape, as a JSON Schema document with `type: \"object\"`. */\n readonly inputSchema: Record<string, unknown>\n /** The tool's structured result shape, when the server disclosed one. */\n readonly outputSchema: Record<string, unknown> | undefined\n}\n\n/**\n * The result of one `tools/call`.\n *\n * MCP tool content is a small union (text, image, embedded resource, …); this\n * client passes every block through by shape rather than modeling the union,\n * since {@link McpFlows} only needs to hand the blocks back to the caller.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface ToolResult {\n readonly content: ReadonlyArray<Record<string, unknown>>\n readonly isError: boolean\n readonly structuredContent: Record<string, unknown> | undefined\n}\n\n/**\n * A live MCP session, holding the tool catalog fetched at connect time and a\n * way to call one of its entries.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface McpClient {\n readonly server: string\n readonly tools: ReadonlyArray<ToolDescription>\n /**\n * Calls one catalogued tool. An unknown name fails with `tool_not_found`\n * before a JSON-RPC frame is written. Declared structured output is checked\n * against the supported output-schema subset before it is returned.\n */\n readonly callTool: (name: string, args: Record<string, unknown>) => Effect.Effect<ToolResult, McpError>\n}\n\n/**\n * Session and catalog limits shared by every transport.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface ClientOptions {\n /** The name this server is known by, for flow naming and error messages. */\n readonly server: string\n /** Deadline for each initialize/catalog request. See {@link defaultHandshakeTimeoutMs}. */\n readonly handshakeTimeoutMs?: number | undefined\n /** Maximum tools accepted across every catalog page. See {@link defaultMaxTools}. */\n readonly maxTools?: number | undefined\n /**\n * Maximum UTF-8 bytes in a tool name. Names also cannot be `.` or `..`, or\n * contain `/`, a control or format character (Unicode categories Cc and Cf,\n * which include bidi and zero-width marks), U+2028, U+2029, or a lone\n * surrogate. See {@link defaultMaxToolNameBytes}.\n */\n readonly maxToolNameBytes?: number | undefined\n /**\n * Maximum UTF-8 bytes of one tool's model-facing text: its description plus\n * its JSON-encoded `inputSchema`. See {@link defaultMaxToolDocumentBytes}.\n */\n readonly maxToolDocumentBytes?: number | undefined\n /** Maximum pages walked while fetching the catalog. See {@link defaultMaxCatalogPages}. */\n readonly maxCatalogPages?: number | undefined\n}\n\n/**\n * A server spawned as a child process and spoken to over its stdio.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface StdioConnectOptions extends StdioTransport.ConnectOptions, ClientOptions {\n readonly url?: never\n}\n\n/**\n * Supplies the bearer credential for a Streamable HTTP server. `token` runs\n * once per HTTP message, so a provider can rotate the credential; its failure\n * fails that message unchanged.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport type AuthProvider = HttpTransport.AuthProvider\n\n/**\n * A remote server reached over MCP Streamable HTTP through the `HttpClient`\n * in context.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface HttpConnectOptions extends HttpTransport.ConnectOptions, ClientOptions {\n readonly command?: never\n}\n\n/**\n * Options accepted by {@link connect}: a stdio command or an HTTP `url`.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type ConnectOptions = StdioConnectOptions | HttpConnectOptions\n\n/**\n * The services {@link connect} needs for the given options: a process spawner\n * for stdio, an `HttpClient` for a `url`.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport type Requirements<O extends ConnectOptions> = O extends { readonly url: string } ? HttpClient.HttpClient\n : ChildProcessSpawner\n\nconst isHttp = (options: ConnectOptions): options is HttpConnectOptions => options.url !== undefined\n\nconst PositiveInteger = Schema.Int.check(Schema.isGreaterThan(0))\n\n/**\n * Authoritative decoder for a persisted stdio MCP server entry.\n *\n * The schema requires non-empty server and command names, string arguments,\n * a plain string-valued environment record, and positive-integer limits.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const ConnectOptionsSchema = Schema.Struct({\n server: Schema.NonEmptyString,\n command: Schema.NonEmptyString,\n args: Schema.Array(Schema.String),\n cwd: Schema.optional(Schema.NonEmptyString),\n env: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n handshakeTimeoutMs: Schema.optional(PositiveInteger),\n requestTimeoutMs: Schema.optional(PositiveInteger),\n queueCapacity: Schema.optional(PositiveInteger),\n maxFrameBytes: Schema.optional(PositiveInteger),\n maxOutboundFrameBytes: Schema.optional(PositiveInteger),\n maxStderrBytes: Schema.optional(PositiveInteger),\n maxTools: Schema.optional(PositiveInteger),\n maxToolNameBytes: Schema.optional(PositiveInteger),\n maxToolDocumentBytes: Schema.optional(PositiveInteger),\n maxCatalogPages: Schema.optional(PositiveInteger)\n})\n\n/** An absolute `http:` or `https:` URL without credentials: userinfo would put a secret in the file. */\nconst isEndpoint = (url: string): boolean => {\n if (!URL.canParse(url)) return false\n const parsed = new URL(url)\n return (parsed.protocol === \"http:\" || parsed.protocol === \"https:\") && parsed.username === \"\" &&\n parsed.password === \"\"\n}\n\n/**\n * Authoritative decoder for a persisted Streamable HTTP MCP server entry.\n *\n * The schema requires a non-empty server name, an absolute `http:` or\n * `https:` `url` without userinfo, and positive-integer limits. A bearer\n * credential is never stored in the entry: `bearerTokenEnv` names the\n * environment variable the host reads it from and turns into an\n * {@link AuthProvider}.\n *\n * @category schemas\n * @since 1.0.0-rc.1\n */\nexport const HttpConnectOptionsSchema = Schema.Struct({\n server: Schema.NonEmptyString,\n url: Schema.String.check(Schema.makeFilter(isEndpoint, { expected: \"an http: or https: URL without credentials\" })),\n bearerTokenEnv: Schema.optionalKey(Schema.String.check(Schema.isPattern(/^[A-Za-z_][A-Za-z0-9_]*$/))),\n handshakeTimeoutMs: Schema.optional(PositiveInteger),\n requestTimeoutMs: Schema.optional(PositiveInteger),\n maxFrameBytes: Schema.optional(PositiveInteger),\n maxOutboundFrameBytes: Schema.optional(PositiveInteger),\n maxTools: Schema.optional(PositiveInteger),\n maxToolNameBytes: Schema.optional(PositiveInteger),\n maxToolDocumentBytes: Schema.optional(PositiveInteger),\n maxCatalogPages: Schema.optional(PositiveInteger)\n})\n\n/**\n * Frozen identity disclosed to every MCP server during initialization.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const clientInfo: { readonly name: string; readonly version: string } = Object.freeze({\n name: \"smithers\",\n version: \"1.0.0-rc.3\"\n})\n\n/**\n * MCP revisions whose `tools/list` and `tools/call` shapes this client\n * decodes. The frozen list always proposes `2025-06-18` first.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const supportedProtocolVersions: ReadonlyArray<string> = Object.freeze([\n \"2025-06-18\",\n \"2025-03-26\",\n \"2024-11-05\"\n])\n\n/**\n * Default deadline for each MCP handshake request.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultHandshakeTimeoutMs = 10_000\n\n/**\n * Default deadline for each tool request.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultRequestTimeoutMs = Transport.defaultRequestTimeoutMs\n\n/**\n * Default number of outbound frames allowed to wait in memory.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultQueueCapacity = StdioTransport.defaultQueueCapacity\n\n/**\n * Default maximum inbound JSON-RPC frame size.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxFrameBytes = Transport.defaultMaxFrameBytes\n\n/**\n * Default maximum outbound JSON-RPC frame size.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxOutboundFrameBytes = Transport.defaultMaxOutboundFrameBytes\n\n/**\n * Default maximum child-stderr tail retained for connection diagnostics.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxStderrBytes = StdioTransport.defaultMaxStderrBytes\n\n/**\n * Default maximum number of tools in a remote catalog.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxTools = 256\n\n/**\n * Default maximum UTF-8 byte length of one remote tool name.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxToolNameBytes = 128\n\n/**\n * Default maximum UTF-8 bytes of one tool's description plus its JSON-encoded\n * `inputSchema`, the server-authored text a model reads for that tool.\n *\n * @category constants\n * @since 1.0.0-rc.1\n */\nexport const defaultMaxToolDocumentBytes = 65_536\n\n/**\n * Default maximum number of remote catalog pages.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxCatalogPages = 32\n\n/**\n * Maximum nested JSON containers, including the JSON-RPC envelope. Fixed so\n * accepted server schemas and values remain safe for recursive consumers.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const maxJsonDepth = JsonLimits.maxDepth\n\nconst invalidResponse = (server: string, message: string): McpError =>\n new McpError({ code: \"invalid_response\", message, server })\n\nconst asInitialize = (server: string, result: unknown): Result.Result<void, McpError> => {\n if (!isRecord(result)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: result is not an object`\n ))\n }\n if (typeof result.protocolVersion !== \"string\") {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: protocolVersion is not a string`\n ))\n }\n if (!supportedProtocolVersions.includes(result.protocolVersion)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" speaks an unsupported protocol version; this client speaks ${\n supportedProtocolVersions.join(\", \")\n }`\n ))\n }\n if (!isRecord(result.capabilities)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: capabilities is not an object`\n ))\n }\n if (!Object.hasOwn(result.capabilities, \"tools\") || !isRecord(result.capabilities.tools)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" does not serve tools: its initialize result declares no tools capability`\n ))\n }\n return Result.succeed(undefined)\n}\n\ntype CatalogLimits = {\n readonly maxTools: number\n readonly maxToolNameBytes: number\n readonly maxToolDocumentBytes: number\n}\n\ntype ToolPage = {\n readonly nextCursor: string | undefined\n}\n\nconst nameEncoder = new TextEncoder()\n\n// Cc covers C0, DEL, and C1. Cf covers bidi overrides and isolates (U+202A-202E,\n// U+2066-2069), zero-width marks (U+200B-200F, U+2060, U+FEFF), and soft hyphen:\n// all invisible text that makes `mcp/<server>/<tool>` read as another tool.\n// Cs catches a lone surrogate, which UTF-8 encoding would silently replace.\nconst forbiddenToolNameCharacter = /[/\\p{Cc}\\p{Cf}\\p{Cs}\\u2028\\u2029]/u\n\nconst isForbiddenToolName = (name: string): boolean =>\n name === \".\" || name === \"..\" || forbiddenToolNameCharacter.test(name)\n\nconst asToolPage = (\n server: string,\n result: unknown,\n limits: CatalogLimits,\n seen: Set<string>,\n described: Array<ToolDescription>\n): Result.Result<ToolPage, McpError> => {\n const tools = isRecord(result) ? result.tools : undefined\n if (!Array.isArray(tools)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/list result with no tools array`\n ))\n }\n for (const [index, tool] of tools.entries()) {\n if (described.length >= limits.maxTools) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned more than ${limits.maxTools} tools`\n ))\n }\n if (!isRecord(tool)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned tools[${index}], which is not an object`\n ))\n }\n const record = tool\n if (typeof record.name !== \"string\" || record.name === \"\") {\n return Result.fail(invalidResponse(server, `MCP server \"${server}\" returned tools[${index}] with no name`))\n }\n if (nameEncoder.encode(record.name).byteLength > limits.maxToolNameBytes) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool name longer than ${limits.maxToolNameBytes} bytes`\n ))\n }\n if (isForbiddenToolName(record.name)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool name that is \".\" or \"..\", or contains \"/\" or an invisible or control character`\n ))\n }\n if (seen.has(record.name)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a duplicate tool name at catalog index ${index}`\n ))\n }\n if (!isRecord(record.inputSchema) || record.inputSchema.type !== \"object\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool whose inputSchema is not a JSON Schema object of type \"object\"`\n ))\n }\n const description = typeof record.description === \"string\" ? record.description : undefined\n const documentBytes = nameEncoder.encode(description ?? \"\").byteLength +\n nameEncoder.encode(JSON.stringify(record.inputSchema)).byteLength\n if (documentBytes > limits.maxToolDocumentBytes) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool description and inputSchema longer than ${limits.maxToolDocumentBytes} bytes`\n ))\n }\n let outputSchema: Record<string, unknown> | undefined\n if (Object.hasOwn(record, \"outputSchema\")) {\n if (!isRecord(record.outputSchema)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool whose outputSchema is not a JSON object`\n ))\n }\n outputSchema = record.outputSchema\n }\n seen.add(record.name)\n described.push({\n name: record.name,\n description,\n inputSchema: record.inputSchema,\n outputSchema\n })\n }\n\n const nextCursor = isRecord(result) && Object.hasOwn(result, \"nextCursor\") ? result.nextCursor : undefined\n if (nextCursor === undefined) return Result.succeed({ nextCursor: undefined })\n if (typeof nextCursor !== \"string\" || nextCursor === \"\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/list cursor that is not a non-empty string`\n ))\n }\n return Result.succeed({ nextCursor })\n}\n\n// Container guards deliberately inspect only the shape; traversal below owns\n// cooperative interruption. Schema.Int excludes unsafe integers, unlike JSON Schema.\nconst outputTypes = {\n null: Schema.Null,\n boolean: Schema.Boolean,\n object: Schema.declare(isRecord),\n array: Schema.declare(Array.isArray),\n number: Schema.Number,\n string: Schema.String,\n integer: Schema.Number.check(Schema.makeFilter(Number.isInteger))\n}\n\n// Every traversal step consumes a slice slot, including enum-key construction.\n// Yielding keeps validation interruptible after the transport has completed.\nconst runJsonWork = <A>(work: Generator<void, A>): Effect.Effect<A> =>\n Effect.gen(function*() {\n while (true) {\n for (let steps = 0; steps < 1_024; steps += 1) {\n const next = work.next()\n if (next.done) return next.value\n }\n yield* Effect.yieldNow\n }\n })\n\n// Keys are canonical JSON: object order is irrelevant, array order is not.\n// Inputs here are depth-checked parsed JSON, never caller-owned arguments.\nconst enumKey = function*(value: unknown): Generator<void, string> {\n yield\n if (Array.isArray(value)) {\n const items: Array<string> = []\n for (const item of value) items.push(yield* enumKey(item))\n return `[${items.join(\",\")}]`\n }\n if (isRecord(value)) {\n const members: Array<string> = []\n for (const key of Object.keys(value).sort()) {\n members.push(`${JSON.stringify(key)}:${yield* enumKey(value[key])}`)\n }\n return `{${members.join(\",\")}}`\n }\n return JSON.stringify(value)\n}\n\ntype OutputValidator = (value: unknown, path: string) => Generator<void, JsonIssue | undefined>\n\n/**\n * Compile the supported output-schema subset once per catalog. Effect Schema\n * owns type unions; this cooperative compatibility traversal retains composite\n * enums, own-property requirements and ignored unsupported keywords. Importing\n * the whole document would enforce constraints this client does not support.\n */\nconst compileOutputSchema = function*(schema: Record<string, unknown>): Generator<void, OutputValidator> {\n yield\n const types = new Set<keyof typeof outputTypes>()\n for (const candidate of Array.isArray(schema.type) ? schema.type : [schema.type]) {\n yield\n if (typeof candidate === \"string\" && Object.hasOwn(outputTypes, candidate)) {\n types.add(candidate as keyof typeof outputTypes)\n }\n }\n const accepts = Schema.is(\n types.size === 0 ? Schema.Unknown : Schema.Union([...types].map((type) => outputTypes[type]))\n )\n const typeReason = `expected ${[...types].join(\" or \")}`\n let enumIndex: Set<string> | undefined\n if (Array.isArray(schema.enum)) {\n enumIndex = new Set()\n for (const member of schema.enum) enumIndex.add(yield* enumKey(member))\n }\n const required: Array<string> = []\n if (Array.isArray(schema.required)) {\n for (const key of schema.required) {\n yield\n if (typeof key === \"string\") required.push(key)\n }\n }\n const properties: Array<readonly [string, OutputValidator]> = []\n if (isRecord(schema.properties)) {\n for (const [key, property] of Object.entries(schema.properties)) {\n yield\n if (isRecord(property)) properties.push([key, yield* compileOutputSchema(property)])\n }\n }\n const items = isRecord(schema.items) ? yield* compileOutputSchema(schema.items) : undefined\n\n return function*(value, path) {\n yield\n if (enumIndex !== undefined && !enumIndex.has(yield* enumKey(value))) {\n return { path, reason: \"expected a declared enum value\" }\n }\n if (!accepts(value)) return { path, reason: typeReason }\n if (isRecord(value)) {\n for (const key of required) {\n yield\n if (!Object.hasOwn(value, key)) return { path: `${path}.${key}`, reason: \"required property is missing\" }\n }\n for (const [key, validate] of properties) {\n yield\n if (!Object.hasOwn(value, key)) continue\n const issue = yield* validate(value[key], `${path}.${key}`)\n if (issue !== undefined) return issue\n }\n }\n if (Array.isArray(value) && items !== undefined) {\n for (const [index, item] of value.entries()) {\n const issue = yield* items(item, `${path}[${index}]`)\n if (issue !== undefined) return issue\n }\n }\n return undefined\n }\n}\n\nconst asToolResult = function*(\n server: string,\n result: unknown,\n outputSchema: Record<string, unknown> | undefined,\n diagnostic: (source: \"invalid-response\", detail: unknown) => void,\n validate: OutputValidator | undefined\n): Generator<void, Result.Result<ToolResult, McpError>> {\n if (!isRecord(result)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result that is not an object`\n ))\n }\n const hasContent = Object.hasOwn(result, \"content\")\n const hasStructuredContent = Object.hasOwn(result, \"structuredContent\")\n if (!hasContent && !hasStructuredContent) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result with no content array`\n ))\n }\n if (hasContent && !Array.isArray(result.content)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result with no content array`\n ))\n }\n const content: Array<Record<string, unknown>> = []\n const blocks = hasContent ? result.content as Array<unknown> : []\n for (const [index, block] of blocks.entries()) {\n yield\n if (!isRecord(block)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose content[${index}] is not an object`\n ))\n }\n content.push(block)\n }\n if (Object.hasOwn(result, \"isError\") && typeof result.isError !== \"boolean\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose isError is not a boolean`\n ))\n }\n let structuredContent: Record<string, unknown> | undefined\n if (hasStructuredContent) {\n if (!isRecord(result.structuredContent)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose structuredContent is not a JSON object`\n ))\n }\n structuredContent = result.structuredContent\n if (validate !== undefined) {\n const issue = yield* validate(structuredContent, \"structuredContent\")\n if (issue !== undefined) {\n diagnostic(\"invalid-response\", { issue, outputSchema })\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned structuredContent that its own outputSchema rejects: ${issue.reason}; property path withheld`\n ))\n }\n }\n }\n return Result.succeed({\n content,\n isError: result.isError === true,\n structuredContent\n })\n}\n\ninterface JsonObject {\n [key: string]: JsonValue\n}\n\ntype JsonValue = null | boolean | number | string | Array<JsonValue> | JsonObject\n\ntype JsonIssue = {\n readonly path: string\n readonly reason: string\n}\n\ntype JsonPath = string | { readonly parent: JsonPath; key: string | number }\n\nconst renderJsonPath = (path: JsonPath): string =>\n typeof path === \"string\" ?\n path :\n `${renderJsonPath(path.parent)}${typeof path.key === \"number\" ? `[${path.key}]` : `.${path.key}`}`\n\nconst jsonFailure = (path: JsonPath, reason: string): Result.Result<JsonValue, JsonIssue> =>\n Result.fail({ path: renderJsonPath(path), reason })\n\nconst reflect = <A>(thunk: () => A): Result.Result<A, string> => {\n try {\n return Result.succeed(thunk())\n } catch {\n return Result.fail(\"a property that threw when read\")\n }\n}\n\nconst ownDescriptors = (object: object): Result.Result<PropertyDescriptorMap, string> =>\n reflect(() => Object.getOwnPropertyDescriptors(object))\n\nconst isAccessor = (descriptor: PropertyDescriptor): boolean =>\n Object.hasOwn(descriptor, \"get\") || Object.hasOwn(descriptor, \"set\")\n\ntype JsonBudget = { remaining: number }\n\n// Lower bounds on encoded size avoid expanding repeated references into an\n// enormous tree before the transport's exact UTF-8 frame check. String/key\n// UTF-16 length is a lower bound even with escapes and surrogate pairs.\nconst spendJson = (budget: JsonBudget, bytes: number): boolean => {\n budget.remaining -= bytes\n return budget.remaining >= 0\n}\n\nconst snapshotJson = (\n value: unknown,\n path: JsonPath,\n ancestors: Set<object>,\n budget: JsonBudget\n): Result.Result<JsonValue, JsonIssue> => {\n const bytes = typeof value === \"string\" ?\n value.length + 2\n : typeof value === \"number\" || typeof value === \"boolean\" ?\n String(value).length\n : value === null ?\n 4\n : 2\n if (!spendJson(budget, bytes)) return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n if (value === null) return Result.succeed(null)\n if (typeof value === \"boolean\" || typeof value === \"string\") return Result.succeed(value)\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? Result.succeed(value) : jsonFailure(path, \"a non-finite number\")\n }\n if (typeof value === \"undefined\") return jsonFailure(path, \"undefined\")\n if (typeof value === \"bigint\") return jsonFailure(path, \"a bigint\")\n if (typeof value === \"function\") return jsonFailure(path, \"a function\")\n if (typeof value === \"symbol\") return jsonFailure(path, \"a symbol\")\n\n if (ancestors.has(value)) return jsonFailure(path, \"a cyclic reference\")\n // Arguments live inside the wire envelope and its params object.\n if (ancestors.size + 3 > maxJsonDepth) return jsonFailure(path, `JSON nesting exceeds ${maxJsonDepth} containers`)\n const array = reflect(() => Array.isArray(value))\n if (Result.isFailure(array)) return jsonFailure(path, array.failure)\n if (array.success) {\n const length = reflect(() => (value as Array<unknown>).length)\n if (Result.isFailure(length)) return jsonFailure(path, length.failure)\n if (!Number.isSafeInteger(length.success) || length.success < 0) {\n return jsonFailure(path, \"a property that threw when read\")\n }\n if (!spendJson(budget, Math.max(0, length.success - 1))) {\n return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n }\n const descriptors = ownDescriptors(value)\n if (Result.isFailure(descriptors)) return jsonFailure(path, descriptors.failure)\n ancestors.add(value)\n const copied: Array<JsonValue> = []\n const memberPath: JsonPath = { parent: path, key: 0 }\n for (let index = 0; index < length.success; index += 1) {\n memberPath.key = index\n // Missing slots must not resolve through Object.prototype.\n const descriptor = Object.hasOwn(descriptors.success, index) ? descriptors.success[index] : undefined\n if (descriptor !== undefined && isAccessor(descriptor)) {\n ancestors.delete(value)\n return jsonFailure(memberPath, \"an accessor property\")\n }\n const member = descriptor === undefined ? undefined : descriptor.value\n const snapshot = snapshotJson(member, memberPath, ancestors, budget)\n if (Result.isFailure(snapshot)) {\n ancestors.delete(value)\n return snapshot\n }\n copied.push(snapshot.success)\n }\n ancestors.delete(value)\n return Result.succeed(copied)\n }\n\n const object = value as Record<string, unknown>\n const prototype = reflect(() => Object.getPrototypeOf(object))\n if (Result.isFailure(prototype)) return jsonFailure(path, prototype.failure)\n if (prototype.success !== Object.prototype && prototype.success !== null) {\n return jsonFailure(path, \"an object with a non-plain prototype\")\n }\n const symbols = reflect(() => Object.getOwnPropertySymbols(object))\n if (Result.isFailure(symbols)) return jsonFailure(path, symbols.failure)\n const descriptors = ownDescriptors(object)\n if (Result.isFailure(descriptors)) return jsonFailure(path, descriptors.failure)\n for (const key of symbols.success) {\n if (Object.hasOwn(descriptors.success, key) && descriptors.success[key]!.enumerable) {\n return jsonFailure(path, \"a symbol-keyed property\")\n }\n }\n\n ancestors.add(object)\n const copied: JsonObject = {}\n let members = 0\n const memberPath: JsonPath = { parent: path, key: \"\" }\n for (const key of Object.keys(descriptors.success)) {\n memberPath.key = key\n const descriptor = descriptors.success[key]!\n if (descriptor.enumerable !== true) continue\n if (!spendJson(budget, key.length + 3 + Math.min(1, members++))) {\n ancestors.delete(object)\n return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n }\n if (isAccessor(descriptor)) {\n ancestors.delete(object)\n return jsonFailure(memberPath, \"an accessor property\")\n }\n const snapshot = snapshotJson(descriptor.value, memberPath, ancestors, budget)\n if (Result.isFailure(snapshot)) {\n ancestors.delete(object)\n return snapshot\n }\n Object.defineProperty(copied, key, {\n configurable: true,\n enumerable: true,\n value: snapshot.success,\n writable: true\n })\n }\n ancestors.delete(object)\n return Result.succeed(copied)\n}\n\nconst snapshotArguments = (\n server: string,\n args: Record<string, unknown>,\n diagnostic: (source: \"invalid-arguments\", detail: unknown) => void,\n maxBytes: number\n): Result.Result<Record<string, unknown>, McpError> => {\n const snapshot = snapshotJson(args, \"arguments\", new Set(), { remaining: maxBytes })\n if (Result.isFailure(snapshot)) {\n diagnostic(\"invalid-arguments\", snapshot.failure)\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" was sent a tool argument that is not JSON: ${snapshot.failure.reason}; property path withheld`\n ))\n }\n if (!isRecord(snapshot.success)) {\n return Result.fail(Limits.protocolError(server, `MCP server \"${server}\" tool arguments must be a JSON object`))\n }\n return Result.succeed(snapshot.success)\n}\n\n/**\n * Connects to an MCP server over stdio (`command`) or Streamable HTTP (`url`),\n * completes the `initialize` handshake, and fetches its tool catalog once, up\n * front. Failed or interrupted setup closes its subprocess, I/O fibers, or\n * HTTP session before returning to the caller; a successful session stays\n * open until the caller scope closes.\n *\n * The tool catalog is a snapshot: a server that changes its tools after\n * connecting (a `notifications/tools/list_changed` push) is not re-polled.\n * {@link McpFlows} rebuilds by reconnecting to refresh.\n * Catalog input schemas must declare `type: \"object\"`. A later tool result may\n * omit `content` when it carries `structuredContent`; a declared output schema\n * is enforced for the documented keyword subset.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const connect = <O extends ConnectOptions>(\n options: O\n): Effect.Effect<McpClient, McpError, Requirements<O> | Scope.Scope> =>\n Effect.acquireUseRelease(\n Effect.flatMap(Effect.scope, Scope.fork),\n (scope) =>\n Effect.gen(function*() {\n const diagnostic = yield* DiagnosticReporter.make(options.server)\n const decodeResponse = <A>(response: unknown, decoded: Result.Result<A, McpError>) =>\n Effect.fromResult(decoded).pipe(\n Effect.tapError(() => Effect.sync(() => diagnostic(\"invalid-response\", response)))\n )\n const handshakeTimeoutMs = options.handshakeTimeoutMs ?? defaultHandshakeTimeoutMs\n const maxArgumentBytes = options.maxOutboundFrameBytes ?? defaultMaxOutboundFrameBytes\n const maxTools = options.maxTools ?? defaultMaxTools\n const maxToolNameBytes = options.maxToolNameBytes ?? defaultMaxToolNameBytes\n const maxToolDocumentBytes = options.maxToolDocumentBytes ?? defaultMaxToolDocumentBytes\n const maxCatalogPages = options.maxCatalogPages ?? defaultMaxCatalogPages\n yield* Limits.checkPositiveIntegers(options.server, [\n [\"handshakeTimeoutMs\", handshakeTimeoutMs],\n [\"maxTools\", maxTools],\n [\"maxToolNameBytes\", maxToolNameBytes],\n [\"maxToolDocumentBytes\", maxToolDocumentBytes],\n [\"maxCatalogPages\", maxCatalogPages]\n ])\n\n const transport: Transport.Transport = yield* (isHttp(options)\n ? HttpTransport.connect(options)\n : StdioTransport.connect(options))\n\n const initialized = yield* transport.request(\n \"initialize\",\n {\n protocolVersion: supportedProtocolVersions[0],\n capabilities: {},\n clientInfo\n },\n handshakeTimeoutMs\n )\n yield* decodeResponse(initialized, asInitialize(options.server, initialized))\n // A notification, not a request: the server never replies to it, and the\n // handshake is not complete until the client sends it.\n yield* transport.notify(\"notifications/initialized\", undefined, handshakeTimeoutMs)\n\n const tools: Array<ToolDescription> = []\n const toolNames = new Set<string>()\n const cursors = new Set<string>()\n let params: Record<string, unknown> = {}\n let pageCount = 0\n while (true) {\n const listed = yield* transport.request(\"tools/list\", params, handshakeTimeoutMs)\n pageCount += 1\n const page = yield* decodeResponse(\n listed,\n asToolPage(\n options.server,\n listed,\n { maxTools, maxToolNameBytes, maxToolDocumentBytes },\n toolNames,\n tools\n )\n )\n if (page.nextCursor === undefined) break\n if (cursors.has(page.nextCursor)) {\n diagnostic(\"invalid-response\", listed)\n return yield* Effect.fail(invalidResponse(\n options.server,\n `MCP server \"${options.server}\" repeated a tools/list cursor`\n ))\n }\n if (pageCount >= maxCatalogPages) {\n return yield* Effect.fail(invalidResponse(\n options.server,\n `MCP server \"${options.server}\" returned more than ${maxCatalogPages} tools/list pages`\n ))\n }\n cursors.add(page.nextCursor)\n params = { cursor: page.nextCursor }\n }\n JsonLimits.freezeParsed(tools)\n const validators = new Map<string, OutputValidator>()\n for (const tool of tools) {\n if (tool.outputSchema !== undefined) {\n validators.set(tool.name, yield* runJsonWork(compileOutputSchema(tool.outputSchema)))\n }\n }\n\n const callTool = (name: string, args: Record<string, unknown>): Effect.Effect<ToolResult, McpError> => {\n const tool = tools.find((candidate) => candidate.name === name)\n if (tool === undefined) {\n return Effect.fail(\n new McpError({\n code: \"tool_not_found\",\n message: `MCP server \"${options.server}\" has no requested tool`,\n server: options.server\n })\n )\n }\n const snapshot = snapshotArguments(options.server, args, diagnostic, maxArgumentBytes)\n if (Result.isFailure(snapshot)) {\n // Do not inspect the rejected object again: it may contain throwing\n // accessors or proxies. Even diagnostic observers see only the safe\n // rejection, never a second traversal of executable user properties.\n return Effect.fail(snapshot.failure)\n }\n return Effect.flatMap(\n transport.request(\"tools/call\", { name, arguments: snapshot.success }),\n (result) =>\n Effect.flatMap(\n runJsonWork(asToolResult(options.server, result, tool.outputSchema, diagnostic, validators.get(name))),\n (decoded) => decodeResponse(result, decoded)\n )\n )\n }\n\n return { server: options.server, tools, callTool }\n }).pipe(Scope.provide(scope)),\n // Closing a failed attempt also detaches it from the caller's scope.\n // Successful sessions remain owned by that scope until it closes.\n (scope, exit) => Exit.isFailure(exit) ? Scope.close(scope, exit) : Effect.void\n ) as Effect.Effect<McpClient, McpError, Requirements<O> | Scope.Scope>\n"]}
|
|
1
|
+
{"version":3,"file":"McpClient.js","sourceRoot":"","sources":["../../src/McpClient.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A minimal MCP client covering the `initialize` handshake, `tools/list`, and\n * `tools/call`, over stdio or Streamable HTTP.\n *\n * This is deliberately not a general MCP SDK. Smithers has exactly one\n * consumer of an MCP session: {@link McpFlows}, which needs a tool catalog\n * and a way to invoke one entry from it, so the client exposes only that.\n * Resources, prompts, sampling, and roots are not wired up; add them here\n * when a flow adapter needs them, not speculatively.\n *\n * @since 1.0.0-rc.0\n */\n\nimport { isRecord } from \"@smthrs/canonical/Record\"\nimport { Effect, Exit, Result, Schema, Scope } from \"effect\"\nimport type * as HttpClient from \"effect/unstable/http/HttpClient\"\nimport type { ChildProcessSpawner } from \"effect/unstable/process/ChildProcessSpawner\"\nimport * as DiagnosticReporter from \"./internal/DiagnosticReporter.ts\"\nimport * as HttpTransport from \"./internal/HttpTransport.ts\"\nimport * as JsonLimits from \"./internal/JsonLimits.ts\"\nimport * as Limits from \"./internal/Limits.ts\"\nimport * as StdioTransport from \"./internal/StdioTransport.ts\"\nimport * as Transport from \"./internal/Transport.ts\"\nimport { McpError } from \"./McpError.ts\"\n\n/**\n * One remote tool as the server describes it.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface ToolDescription {\n readonly name: string\n readonly description: string | undefined\n /** The tool's parameter shape, as a JSON Schema document with `type: \"object\"`. */\n readonly inputSchema: Record<string, unknown>\n /** The tool's structured result shape, when the server disclosed one. */\n readonly outputSchema: Record<string, unknown> | undefined\n}\n\n/**\n * The result of one `tools/call`.\n *\n * MCP tool content is a small union (text, image, embedded resource, …); this\n * client passes every block through by shape rather than modeling the union,\n * since {@link McpFlows} only needs to hand the blocks back to the caller.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface ToolResult {\n readonly content: ReadonlyArray<Record<string, unknown>>\n readonly isError: boolean\n readonly structuredContent: Record<string, unknown> | undefined\n}\n\n/**\n * A live MCP session, holding the tool catalog fetched at connect time and a\n * way to call one of its entries.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface McpClient {\n readonly server: string\n readonly tools: ReadonlyArray<ToolDescription>\n /**\n * Calls one catalogued tool. An unknown name fails with `tool_not_found`\n * before a JSON-RPC frame is written. Declared structured output is checked\n * against the supported output-schema subset before it is returned.\n */\n readonly callTool: (name: string, args: Record<string, unknown>) => Effect.Effect<ToolResult, McpError>\n}\n\n/**\n * Session and catalog limits shared by every transport.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface ClientOptions {\n /** The name this server is known by, for flow naming and error messages. */\n readonly server: string\n /** Deadline for each initialize/catalog request. See {@link defaultHandshakeTimeoutMs}. */\n readonly handshakeTimeoutMs?: number | undefined\n /** Maximum tools accepted across every catalog page. See {@link defaultMaxTools}. */\n readonly maxTools?: number | undefined\n /**\n * Maximum UTF-8 bytes in a tool name. Names also cannot be `.` or `..`, or\n * contain `/`, a control or format character (Unicode categories Cc and Cf,\n * which include bidi and zero-width marks), U+2028, U+2029, or a lone\n * surrogate. See {@link defaultMaxToolNameBytes}.\n */\n readonly maxToolNameBytes?: number | undefined\n /**\n * Maximum UTF-8 bytes of one tool's model-facing text: its description plus\n * its JSON-encoded `inputSchema`. See {@link defaultMaxToolDocumentBytes}.\n */\n readonly maxToolDocumentBytes?: number | undefined\n /** Maximum pages walked while fetching the catalog. See {@link defaultMaxCatalogPages}. */\n readonly maxCatalogPages?: number | undefined\n}\n\n/**\n * A server spawned as a child process and spoken to over its stdio.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface StdioConnectOptions extends StdioTransport.ConnectOptions, ClientOptions {\n readonly url?: never\n}\n\n/**\n * Supplies the bearer credential for a Streamable HTTP server. `token` runs\n * once per HTTP message, so a provider can rotate the credential; its failure\n * fails that message unchanged.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport type AuthProvider = HttpTransport.AuthProvider\n\n/**\n * A remote server reached over MCP Streamable HTTP through the `HttpClient`\n * in context.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface HttpConnectOptions extends HttpTransport.ConnectOptions, ClientOptions {\n readonly command?: never\n}\n\n/**\n * Options accepted by {@link connect}: a stdio command or an HTTP `url`.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type ConnectOptions = StdioConnectOptions | HttpConnectOptions\n\n/**\n * The services {@link connect} needs for the given options: a process spawner\n * for stdio, an `HttpClient` for a `url`.\n *\n * @category models\n * @since 1.0.0-rc.1\n */\nexport type Requirements<O extends ConnectOptions> = O extends { readonly url: string } ? HttpClient.HttpClient\n : ChildProcessSpawner\n\nconst isHttp = (options: ConnectOptions): options is HttpConnectOptions => options.url !== undefined\n\nconst PositiveInteger = Schema.Int.check(Schema.isGreaterThan(0))\n\n/**\n * Authoritative decoder for a persisted stdio MCP server entry.\n *\n * The schema requires non-empty server and command names, string arguments,\n * a plain string-valued environment record, and positive-integer limits.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const ConnectOptionsSchema = Schema.Struct({\n server: Schema.NonEmptyString,\n command: Schema.NonEmptyString,\n args: Schema.Array(Schema.String),\n cwd: Schema.optional(Schema.NonEmptyString),\n env: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n handshakeTimeoutMs: Schema.optional(PositiveInteger),\n requestTimeoutMs: Schema.optional(PositiveInteger),\n queueCapacity: Schema.optional(PositiveInteger),\n maxFrameBytes: Schema.optional(PositiveInteger),\n maxOutboundFrameBytes: Schema.optional(PositiveInteger),\n maxStderrBytes: Schema.optional(PositiveInteger),\n maxTools: Schema.optional(PositiveInteger),\n maxToolNameBytes: Schema.optional(PositiveInteger),\n maxToolDocumentBytes: Schema.optional(PositiveInteger),\n maxCatalogPages: Schema.optional(PositiveInteger)\n})\n\n/** An absolute `http:` or `https:` URL without credentials: userinfo would put a secret in the file. */\nconst isEndpoint = (url: string): boolean => {\n if (!URL.canParse(url)) return false\n const parsed = new URL(url)\n return (parsed.protocol === \"http:\" || parsed.protocol === \"https:\") && parsed.username === \"\" &&\n parsed.password === \"\"\n}\n\n/**\n * Authoritative decoder for a persisted Streamable HTTP MCP server entry.\n *\n * The schema requires a non-empty server name, an absolute `http:` or\n * `https:` `url` without userinfo, and positive-integer limits. A bearer\n * credential is never stored in the entry: `bearerTokenEnv` names the\n * environment variable the host reads it from and turns into an\n * {@link AuthProvider}.\n *\n * @category schemas\n * @since 1.0.0-rc.1\n */\nexport const HttpConnectOptionsSchema = Schema.Struct({\n server: Schema.NonEmptyString,\n url: Schema.String.check(Schema.makeFilter(isEndpoint, { expected: \"an http: or https: URL without credentials\" })),\n bearerTokenEnv: Schema.optionalKey(Schema.String.check(Schema.isPattern(/^[A-Za-z_][A-Za-z0-9_]*$/))),\n handshakeTimeoutMs: Schema.optional(PositiveInteger),\n requestTimeoutMs: Schema.optional(PositiveInteger),\n maxFrameBytes: Schema.optional(PositiveInteger),\n maxOutboundFrameBytes: Schema.optional(PositiveInteger),\n maxTools: Schema.optional(PositiveInteger),\n maxToolNameBytes: Schema.optional(PositiveInteger),\n maxToolDocumentBytes: Schema.optional(PositiveInteger),\n maxCatalogPages: Schema.optional(PositiveInteger)\n})\n\n/**\n * Frozen identity disclosed to every MCP server during initialization.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const clientInfo: { readonly name: string; readonly version: string } = Object.freeze({\n name: \"smithers\",\n version: \"1.0.0-rc.4\"\n})\n\n/**\n * MCP revisions whose `tools/list` and `tools/call` shapes this client\n * decodes. The frozen list always proposes `2025-06-18` first.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const supportedProtocolVersions: ReadonlyArray<string> = Object.freeze([\n \"2025-06-18\",\n \"2025-03-26\",\n \"2024-11-05\"\n])\n\n/**\n * Default deadline for each MCP handshake request.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultHandshakeTimeoutMs = 10_000\n\n/**\n * Default deadline for each tool request.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultRequestTimeoutMs = Transport.defaultRequestTimeoutMs\n\n/**\n * Default number of outbound frames allowed to wait in memory.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultQueueCapacity = StdioTransport.defaultQueueCapacity\n\n/**\n * Default maximum inbound JSON-RPC frame size.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxFrameBytes = Transport.defaultMaxFrameBytes\n\n/**\n * Default maximum outbound JSON-RPC frame size.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxOutboundFrameBytes = Transport.defaultMaxOutboundFrameBytes\n\n/**\n * Default maximum child-stderr tail retained for connection diagnostics.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxStderrBytes = StdioTransport.defaultMaxStderrBytes\n\n/**\n * Default maximum number of tools in a remote catalog.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxTools = 256\n\n/**\n * Default maximum UTF-8 byte length of one remote tool name.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxToolNameBytes = 128\n\n/**\n * Default maximum UTF-8 bytes of one tool's description plus its JSON-encoded\n * `inputSchema`, the server-authored text a model reads for that tool.\n *\n * @category constants\n * @since 1.0.0-rc.1\n */\nexport const defaultMaxToolDocumentBytes = 65_536\n\n/**\n * Default maximum number of remote catalog pages.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const defaultMaxCatalogPages = 32\n\n/**\n * Maximum nested JSON containers, including the JSON-RPC envelope. Fixed so\n * accepted server schemas and values remain safe for recursive consumers.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const maxJsonDepth = JsonLimits.maxDepth\n\nconst invalidResponse = (server: string, message: string): McpError =>\n new McpError({ code: \"invalid_response\", message, server })\n\nconst asInitialize = (server: string, result: unknown): Result.Result<void, McpError> => {\n if (!isRecord(result)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: result is not an object`\n ))\n }\n if (typeof result.protocolVersion !== \"string\") {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: protocolVersion is not a string`\n ))\n }\n if (!supportedProtocolVersions.includes(result.protocolVersion)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" speaks an unsupported protocol version; this client speaks ${\n supportedProtocolVersions.join(\", \")\n }`\n ))\n }\n if (!isRecord(result.capabilities)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" returned a malformed initialize result: capabilities is not an object`\n ))\n }\n if (!Object.hasOwn(result.capabilities, \"tools\") || !isRecord(result.capabilities.tools)) {\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" does not serve tools: its initialize result declares no tools capability`\n ))\n }\n return Result.succeed(undefined)\n}\n\ntype CatalogLimits = {\n readonly maxTools: number\n readonly maxToolNameBytes: number\n readonly maxToolDocumentBytes: number\n}\n\ntype ToolPage = {\n readonly nextCursor: string | undefined\n}\n\nconst nameEncoder = new TextEncoder()\n\n// Cc covers C0, DEL, and C1. Cf covers bidi overrides and isolates (U+202A-202E,\n// U+2066-2069), zero-width marks (U+200B-200F, U+2060, U+FEFF), and soft hyphen:\n// all invisible text that makes `mcp/<server>/<tool>` read as another tool.\n// Cs catches a lone surrogate, which UTF-8 encoding would silently replace.\nconst forbiddenToolNameCharacter = /[/\\p{Cc}\\p{Cf}\\p{Cs}\\u2028\\u2029]/u\n\nconst isForbiddenToolName = (name: string): boolean =>\n name === \".\" || name === \"..\" || forbiddenToolNameCharacter.test(name)\n\nconst asToolPage = (\n server: string,\n result: unknown,\n limits: CatalogLimits,\n seen: Set<string>,\n described: Array<ToolDescription>\n): Result.Result<ToolPage, McpError> => {\n const tools = isRecord(result) ? result.tools : undefined\n if (!Array.isArray(tools)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/list result with no tools array`\n ))\n }\n for (const [index, tool] of tools.entries()) {\n if (described.length >= limits.maxTools) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned more than ${limits.maxTools} tools`\n ))\n }\n if (!isRecord(tool)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned tools[${index}], which is not an object`\n ))\n }\n const record = tool\n if (typeof record.name !== \"string\" || record.name === \"\") {\n return Result.fail(invalidResponse(server, `MCP server \"${server}\" returned tools[${index}] with no name`))\n }\n if (nameEncoder.encode(record.name).byteLength > limits.maxToolNameBytes) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool name longer than ${limits.maxToolNameBytes} bytes`\n ))\n }\n if (isForbiddenToolName(record.name)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool name that is \".\" or \"..\", or contains \"/\" or an invisible or control character`\n ))\n }\n if (seen.has(record.name)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a duplicate tool name at catalog index ${index}`\n ))\n }\n if (!isRecord(record.inputSchema) || record.inputSchema.type !== \"object\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool whose inputSchema is not a JSON Schema object of type \"object\"`\n ))\n }\n const description = typeof record.description === \"string\" ? record.description : undefined\n const documentBytes = nameEncoder.encode(description ?? \"\").byteLength +\n nameEncoder.encode(JSON.stringify(record.inputSchema)).byteLength\n if (documentBytes > limits.maxToolDocumentBytes) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool description and inputSchema longer than ${limits.maxToolDocumentBytes} bytes`\n ))\n }\n let outputSchema: Record<string, unknown> | undefined\n if (Object.hasOwn(record, \"outputSchema\")) {\n if (!isRecord(record.outputSchema)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tool whose outputSchema is not a JSON object`\n ))\n }\n outputSchema = record.outputSchema\n }\n seen.add(record.name)\n described.push({\n name: record.name,\n description,\n inputSchema: record.inputSchema,\n outputSchema\n })\n }\n\n const nextCursor = isRecord(result) && Object.hasOwn(result, \"nextCursor\") ? result.nextCursor : undefined\n if (nextCursor === undefined) return Result.succeed({ nextCursor: undefined })\n if (typeof nextCursor !== \"string\" || nextCursor === \"\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/list cursor that is not a non-empty string`\n ))\n }\n return Result.succeed({ nextCursor })\n}\n\n// Container guards deliberately inspect only the shape; traversal below owns\n// cooperative interruption. Schema.Int excludes unsafe integers, unlike JSON Schema.\nconst outputTypes = {\n null: Schema.Null,\n boolean: Schema.Boolean,\n object: Schema.declare(isRecord),\n array: Schema.declare(Array.isArray),\n number: Schema.Number,\n string: Schema.String,\n integer: Schema.Number.check(Schema.makeFilter(Number.isInteger))\n}\n\n// Every traversal step consumes a slice slot, including enum-key construction.\n// Yielding keeps validation interruptible after the transport has completed.\nconst runJsonWork = <A>(work: Generator<void, A>): Effect.Effect<A> =>\n Effect.gen(function*() {\n while (true) {\n for (let steps = 0; steps < 1_024; steps += 1) {\n const next = work.next()\n if (next.done) return next.value\n }\n yield* Effect.yieldNow\n }\n })\n\n// Keys are canonical JSON: object order is irrelevant, array order is not.\n// Inputs here are depth-checked parsed JSON, never caller-owned arguments.\nconst enumKey = function*(value: unknown): Generator<void, string> {\n yield\n if (Array.isArray(value)) {\n const items: Array<string> = []\n for (const item of value) items.push(yield* enumKey(item))\n return `[${items.join(\",\")}]`\n }\n if (isRecord(value)) {\n const members: Array<string> = []\n for (const key of Object.keys(value).sort()) {\n members.push(`${JSON.stringify(key)}:${yield* enumKey(value[key])}`)\n }\n return `{${members.join(\",\")}}`\n }\n return JSON.stringify(value)\n}\n\ntype OutputValidator = (value: unknown, path: string) => Generator<void, JsonIssue | undefined>\n\n/**\n * Compile the supported output-schema subset once per catalog. Effect Schema\n * owns type unions; this cooperative compatibility traversal retains composite\n * enums, own-property requirements and ignored unsupported keywords. Importing\n * the whole document would enforce constraints this client does not support.\n */\nconst compileOutputSchema = function*(schema: Record<string, unknown>): Generator<void, OutputValidator> {\n yield\n const types = new Set<keyof typeof outputTypes>()\n for (const candidate of Array.isArray(schema.type) ? schema.type : [schema.type]) {\n yield\n if (typeof candidate === \"string\" && Object.hasOwn(outputTypes, candidate)) {\n types.add(candidate as keyof typeof outputTypes)\n }\n }\n const accepts = Schema.is(\n types.size === 0 ? Schema.Unknown : Schema.Union([...types].map((type) => outputTypes[type]))\n )\n const typeReason = `expected ${[...types].join(\" or \")}`\n let enumIndex: Set<string> | undefined\n if (Array.isArray(schema.enum)) {\n enumIndex = new Set()\n for (const member of schema.enum) enumIndex.add(yield* enumKey(member))\n }\n const required: Array<string> = []\n if (Array.isArray(schema.required)) {\n for (const key of schema.required) {\n yield\n if (typeof key === \"string\") required.push(key)\n }\n }\n const properties: Array<readonly [string, OutputValidator]> = []\n if (isRecord(schema.properties)) {\n for (const [key, property] of Object.entries(schema.properties)) {\n yield\n if (isRecord(property)) properties.push([key, yield* compileOutputSchema(property)])\n }\n }\n const items = isRecord(schema.items) ? yield* compileOutputSchema(schema.items) : undefined\n\n return function*(value, path) {\n yield\n if (enumIndex !== undefined && !enumIndex.has(yield* enumKey(value))) {\n return { path, reason: \"expected a declared enum value\" }\n }\n if (!accepts(value)) return { path, reason: typeReason }\n if (isRecord(value)) {\n for (const key of required) {\n yield\n if (!Object.hasOwn(value, key)) return { path: `${path}.${key}`, reason: \"required property is missing\" }\n }\n for (const [key, validate] of properties) {\n yield\n if (!Object.hasOwn(value, key)) continue\n const issue = yield* validate(value[key], `${path}.${key}`)\n if (issue !== undefined) return issue\n }\n }\n if (Array.isArray(value) && items !== undefined) {\n for (const [index, item] of value.entries()) {\n const issue = yield* items(item, `${path}[${index}]`)\n if (issue !== undefined) return issue\n }\n }\n return undefined\n }\n}\n\nconst asToolResult = function*(\n server: string,\n result: unknown,\n outputSchema: Record<string, unknown> | undefined,\n diagnostic: (source: \"invalid-response\", detail: unknown) => void,\n validate: OutputValidator | undefined\n): Generator<void, Result.Result<ToolResult, McpError>> {\n if (!isRecord(result)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result that is not an object`\n ))\n }\n const hasContent = Object.hasOwn(result, \"content\")\n const hasStructuredContent = Object.hasOwn(result, \"structuredContent\")\n if (!hasContent && !hasStructuredContent) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result with no content array`\n ))\n }\n if (hasContent && !Array.isArray(result.content)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result with no content array`\n ))\n }\n const content: Array<Record<string, unknown>> = []\n const blocks = hasContent ? result.content as Array<unknown> : []\n for (const [index, block] of blocks.entries()) {\n yield\n if (!isRecord(block)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose content[${index}] is not an object`\n ))\n }\n content.push(block)\n }\n if (Object.hasOwn(result, \"isError\") && typeof result.isError !== \"boolean\") {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose isError is not a boolean`\n ))\n }\n let structuredContent: Record<string, unknown> | undefined\n if (hasStructuredContent) {\n if (!isRecord(result.structuredContent)) {\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned a tools/call result whose structuredContent is not a JSON object`\n ))\n }\n structuredContent = result.structuredContent\n if (validate !== undefined) {\n const issue = yield* validate(structuredContent, \"structuredContent\")\n if (issue !== undefined) {\n diagnostic(\"invalid-response\", { issue, outputSchema })\n return Result.fail(invalidResponse(\n server,\n `MCP server \"${server}\" returned structuredContent that its own outputSchema rejects: ${issue.reason}; property path withheld`\n ))\n }\n }\n }\n return Result.succeed({\n content,\n isError: result.isError === true,\n structuredContent\n })\n}\n\ninterface JsonObject {\n [key: string]: JsonValue\n}\n\ntype JsonValue = null | boolean | number | string | Array<JsonValue> | JsonObject\n\ntype JsonIssue = {\n readonly path: string\n readonly reason: string\n}\n\ntype JsonPath = string | { readonly parent: JsonPath; key: string | number }\n\nconst renderJsonPath = (path: JsonPath): string =>\n typeof path === \"string\" ?\n path :\n `${renderJsonPath(path.parent)}${typeof path.key === \"number\" ? `[${path.key}]` : `.${path.key}`}`\n\nconst jsonFailure = (path: JsonPath, reason: string): Result.Result<JsonValue, JsonIssue> =>\n Result.fail({ path: renderJsonPath(path), reason })\n\nconst reflect = <A>(thunk: () => A): Result.Result<A, string> => {\n try {\n return Result.succeed(thunk())\n } catch {\n return Result.fail(\"a property that threw when read\")\n }\n}\n\nconst ownDescriptors = (object: object): Result.Result<PropertyDescriptorMap, string> =>\n reflect(() => Object.getOwnPropertyDescriptors(object))\n\nconst isAccessor = (descriptor: PropertyDescriptor): boolean =>\n Object.hasOwn(descriptor, \"get\") || Object.hasOwn(descriptor, \"set\")\n\ntype JsonBudget = { remaining: number }\n\n// Lower bounds on encoded size avoid expanding repeated references into an\n// enormous tree before the transport's exact UTF-8 frame check. String/key\n// UTF-16 length is a lower bound even with escapes and surrogate pairs.\nconst spendJson = (budget: JsonBudget, bytes: number): boolean => {\n budget.remaining -= bytes\n return budget.remaining >= 0\n}\n\nconst snapshotJson = (\n value: unknown,\n path: JsonPath,\n ancestors: Set<object>,\n budget: JsonBudget\n): Result.Result<JsonValue, JsonIssue> => {\n const bytes = typeof value === \"string\" ?\n value.length + 2\n : typeof value === \"number\" || typeof value === \"boolean\" ?\n String(value).length\n : value === null ?\n 4\n : 2\n if (!spendJson(budget, bytes)) return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n if (value === null) return Result.succeed(null)\n if (typeof value === \"boolean\" || typeof value === \"string\") return Result.succeed(value)\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? Result.succeed(value) : jsonFailure(path, \"a non-finite number\")\n }\n if (typeof value === \"undefined\") return jsonFailure(path, \"undefined\")\n if (typeof value === \"bigint\") return jsonFailure(path, \"a bigint\")\n if (typeof value === \"function\") return jsonFailure(path, \"a function\")\n if (typeof value === \"symbol\") return jsonFailure(path, \"a symbol\")\n\n if (ancestors.has(value)) return jsonFailure(path, \"a cyclic reference\")\n // Arguments live inside the wire envelope and its params object.\n if (ancestors.size + 3 > maxJsonDepth) return jsonFailure(path, `JSON nesting exceeds ${maxJsonDepth} containers`)\n const array = reflect(() => Array.isArray(value))\n if (Result.isFailure(array)) return jsonFailure(path, array.failure)\n if (array.success) {\n const length = reflect(() => (value as Array<unknown>).length)\n if (Result.isFailure(length)) return jsonFailure(path, length.failure)\n if (!Number.isSafeInteger(length.success) || length.success < 0) {\n return jsonFailure(path, \"a property that threw when read\")\n }\n if (!spendJson(budget, Math.max(0, length.success - 1))) {\n return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n }\n const descriptors = ownDescriptors(value)\n if (Result.isFailure(descriptors)) return jsonFailure(path, descriptors.failure)\n ancestors.add(value)\n const copied: Array<JsonValue> = []\n const memberPath: JsonPath = { parent: path, key: 0 }\n for (let index = 0; index < length.success; index += 1) {\n memberPath.key = index\n // Missing slots must not resolve through Object.prototype.\n const descriptor = Object.hasOwn(descriptors.success, index) ? descriptors.success[index] : undefined\n if (descriptor !== undefined && isAccessor(descriptor)) {\n ancestors.delete(value)\n return jsonFailure(memberPath, \"an accessor property\")\n }\n const member = descriptor === undefined ? undefined : descriptor.value\n const snapshot = snapshotJson(member, memberPath, ancestors, budget)\n if (Result.isFailure(snapshot)) {\n ancestors.delete(value)\n return snapshot\n }\n copied.push(snapshot.success)\n }\n ancestors.delete(value)\n return Result.succeed(copied)\n }\n\n const object = value as Record<string, unknown>\n const prototype = reflect(() => Object.getPrototypeOf(object))\n if (Result.isFailure(prototype)) return jsonFailure(path, prototype.failure)\n if (prototype.success !== Object.prototype && prototype.success !== null) {\n return jsonFailure(path, \"an object with a non-plain prototype\")\n }\n const symbols = reflect(() => Object.getOwnPropertySymbols(object))\n if (Result.isFailure(symbols)) return jsonFailure(path, symbols.failure)\n const descriptors = ownDescriptors(object)\n if (Result.isFailure(descriptors)) return jsonFailure(path, descriptors.failure)\n for (const key of symbols.success) {\n if (Object.hasOwn(descriptors.success, key) && descriptors.success[key]!.enumerable) {\n return jsonFailure(path, \"a symbol-keyed property\")\n }\n }\n\n ancestors.add(object)\n const copied: JsonObject = {}\n let members = 0\n const memberPath: JsonPath = { parent: path, key: \"\" }\n for (const key of Object.keys(descriptors.success)) {\n memberPath.key = key\n const descriptor = descriptors.success[key]!\n if (descriptor.enumerable !== true) continue\n if (!spendJson(budget, key.length + 3 + Math.min(1, members++))) {\n ancestors.delete(object)\n return jsonFailure(path, \"JSON expansion exceeds the outbound frame budget\")\n }\n if (isAccessor(descriptor)) {\n ancestors.delete(object)\n return jsonFailure(memberPath, \"an accessor property\")\n }\n const snapshot = snapshotJson(descriptor.value, memberPath, ancestors, budget)\n if (Result.isFailure(snapshot)) {\n ancestors.delete(object)\n return snapshot\n }\n Object.defineProperty(copied, key, {\n configurable: true,\n enumerable: true,\n value: snapshot.success,\n writable: true\n })\n }\n ancestors.delete(object)\n return Result.succeed(copied)\n}\n\nconst snapshotArguments = (\n server: string,\n args: Record<string, unknown>,\n diagnostic: (source: \"invalid-arguments\", detail: unknown) => void,\n maxBytes: number\n): Result.Result<Record<string, unknown>, McpError> => {\n const snapshot = snapshotJson(args, \"arguments\", new Set(), { remaining: maxBytes })\n if (Result.isFailure(snapshot)) {\n diagnostic(\"invalid-arguments\", snapshot.failure)\n return Result.fail(Limits.protocolError(\n server,\n `MCP server \"${server}\" was sent a tool argument that is not JSON: ${snapshot.failure.reason}; property path withheld`\n ))\n }\n if (!isRecord(snapshot.success)) {\n return Result.fail(Limits.protocolError(server, `MCP server \"${server}\" tool arguments must be a JSON object`))\n }\n return Result.succeed(snapshot.success)\n}\n\n/**\n * Connects to an MCP server over stdio (`command`) or Streamable HTTP (`url`),\n * completes the `initialize` handshake, and fetches its tool catalog once, up\n * front. Failed or interrupted setup closes its subprocess, I/O fibers, or\n * HTTP session before returning to the caller; a successful session stays\n * open until the caller scope closes.\n *\n * The tool catalog is a snapshot: a server that changes its tools after\n * connecting (a `notifications/tools/list_changed` push) is not re-polled.\n * {@link McpFlows} rebuilds by reconnecting to refresh.\n * Catalog input schemas must declare `type: \"object\"`. A later tool result may\n * omit `content` when it carries `structuredContent`; a declared output schema\n * is enforced for the documented keyword subset.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const connect = <O extends ConnectOptions>(\n options: O\n): Effect.Effect<McpClient, McpError, Requirements<O> | Scope.Scope> =>\n Effect.acquireUseRelease(\n Effect.flatMap(Effect.scope, Scope.fork),\n (scope) =>\n Effect.gen(function*() {\n const diagnostic = yield* DiagnosticReporter.make(options.server)\n const decodeResponse = <A>(response: unknown, decoded: Result.Result<A, McpError>) =>\n Effect.fromResult(decoded).pipe(\n Effect.tapError(() => Effect.sync(() => diagnostic(\"invalid-response\", response)))\n )\n const handshakeTimeoutMs = options.handshakeTimeoutMs ?? defaultHandshakeTimeoutMs\n const maxArgumentBytes = options.maxOutboundFrameBytes ?? defaultMaxOutboundFrameBytes\n const maxTools = options.maxTools ?? defaultMaxTools\n const maxToolNameBytes = options.maxToolNameBytes ?? defaultMaxToolNameBytes\n const maxToolDocumentBytes = options.maxToolDocumentBytes ?? defaultMaxToolDocumentBytes\n const maxCatalogPages = options.maxCatalogPages ?? defaultMaxCatalogPages\n yield* Limits.checkPositiveIntegers(options.server, [\n [\"handshakeTimeoutMs\", handshakeTimeoutMs],\n [\"maxTools\", maxTools],\n [\"maxToolNameBytes\", maxToolNameBytes],\n [\"maxToolDocumentBytes\", maxToolDocumentBytes],\n [\"maxCatalogPages\", maxCatalogPages]\n ])\n\n const transport: Transport.Transport = yield* (isHttp(options)\n ? HttpTransport.connect(options)\n : StdioTransport.connect(options))\n\n const initialized = yield* transport.request(\n \"initialize\",\n {\n protocolVersion: supportedProtocolVersions[0],\n capabilities: {},\n clientInfo\n },\n handshakeTimeoutMs\n )\n yield* decodeResponse(initialized, asInitialize(options.server, initialized))\n // A notification, not a request: the server never replies to it, and the\n // handshake is not complete until the client sends it.\n yield* transport.notify(\"notifications/initialized\", undefined, handshakeTimeoutMs)\n\n const tools: Array<ToolDescription> = []\n const toolNames = new Set<string>()\n const cursors = new Set<string>()\n let params: Record<string, unknown> = {}\n let pageCount = 0\n while (true) {\n const listed = yield* transport.request(\"tools/list\", params, handshakeTimeoutMs)\n pageCount += 1\n const page = yield* decodeResponse(\n listed,\n asToolPage(\n options.server,\n listed,\n { maxTools, maxToolNameBytes, maxToolDocumentBytes },\n toolNames,\n tools\n )\n )\n if (page.nextCursor === undefined) break\n if (cursors.has(page.nextCursor)) {\n diagnostic(\"invalid-response\", listed)\n return yield* Effect.fail(invalidResponse(\n options.server,\n `MCP server \"${options.server}\" repeated a tools/list cursor`\n ))\n }\n if (pageCount >= maxCatalogPages) {\n return yield* Effect.fail(invalidResponse(\n options.server,\n `MCP server \"${options.server}\" returned more than ${maxCatalogPages} tools/list pages`\n ))\n }\n cursors.add(page.nextCursor)\n params = { cursor: page.nextCursor }\n }\n JsonLimits.freezeParsed(tools)\n const validators = new Map<string, OutputValidator>()\n for (const tool of tools) {\n if (tool.outputSchema !== undefined) {\n validators.set(tool.name, yield* runJsonWork(compileOutputSchema(tool.outputSchema)))\n }\n }\n\n const callTool = (name: string, args: Record<string, unknown>): Effect.Effect<ToolResult, McpError> => {\n const tool = tools.find((candidate) => candidate.name === name)\n if (tool === undefined) {\n return Effect.fail(\n new McpError({\n code: \"tool_not_found\",\n message: `MCP server \"${options.server}\" has no requested tool`,\n server: options.server\n })\n )\n }\n const snapshot = snapshotArguments(options.server, args, diagnostic, maxArgumentBytes)\n if (Result.isFailure(snapshot)) {\n // Do not inspect the rejected object again: it may contain throwing\n // accessors or proxies. Even diagnostic observers see only the safe\n // rejection, never a second traversal of executable user properties.\n return Effect.fail(snapshot.failure)\n }\n return Effect.flatMap(\n transport.request(\"tools/call\", { name, arguments: snapshot.success }),\n (result) =>\n Effect.flatMap(\n runJsonWork(asToolResult(options.server, result, tool.outputSchema, diagnostic, validators.get(name))),\n (decoded) => decodeResponse(result, decoded)\n )\n )\n }\n\n return { server: options.server, tools, callTool }\n }).pipe(Scope.provide(scope)),\n // Closing a failed attempt also detaches it from the caller's scope.\n // Successful sessions remain owned by that scope until it closes.\n (scope, exit) => Exit.isFailure(exit) ? Scope.close(scope, exit) : Effect.void\n ) as Effect.Effect<McpClient, McpError, Requirements<O> | Scope.Scope>\n"]}
|
package/dist/esm/McpFlows.d.ts
CHANGED
|
@@ -51,8 +51,9 @@ export declare const Result: Schema.Struct<{
|
|
|
51
51
|
* rejects anything that does not have exactly those three colon-separated
|
|
52
52
|
* components. An unparseable declaration counts as unauthorized. The list is
|
|
53
53
|
* derived from `Capability.Action.literals`, so adding a host action cannot
|
|
54
|
-
* silently omit it from MCP tools, and it is frozen
|
|
55
|
-
*
|
|
54
|
+
* silently omit it from MCP tools, and it is frozen so no caller can narrow
|
|
55
|
+
* or widen what every tool declares. Each binding records it deduplicated and
|
|
56
|
+
* sorted, as `FlowBinding.make` records every declaration.
|
|
56
57
|
*
|
|
57
58
|
* @category constants
|
|
58
59
|
* @since 1.0.0-rc.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpFlows.d.ts","sourceRoot":"","sources":["../../src/McpFlows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAA;AAC/C,OAAO,KAAK,WAAW,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,MAAM,EAAQ,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACpD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,+CAA+C,CAAA;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,MAAM;;;;EAIjB,CAAA;AAEF
|
|
1
|
+
{"version":3,"file":"McpFlows.d.ts","sourceRoot":"","sources":["../../src/McpFlows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAA;AAC/C,OAAO,KAAK,WAAW,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,MAAM,EAAQ,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACpD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,+CAA+C,CAAA;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,MAAM;;;;EAIjB,CAAA;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC,MAAM,CAE9C,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,OAAO,qBAMlB,CAAA;AAEF;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;IACpD,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;IACpD,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACzC;AAwCD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,GAAG,GAAI,QAAQ,SAAS,CAAC,SAAS,EAAE,UAAS,iBAAsB,KAAG,WAAW,CAAC,MAU9F,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,SAAS,CAAC,cAAc,EAC1D,SAAS,CAAC,GAAG,iBAAiB,KAC7B,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAgClF,CAAA"}
|
package/dist/esm/McpFlows.js
CHANGED
|
@@ -52,8 +52,9 @@ export const Result = Schema.Struct({
|
|
|
52
52
|
* rejects anything that does not have exactly those three colon-separated
|
|
53
53
|
* components. An unparseable declaration counts as unauthorized. The list is
|
|
54
54
|
* derived from `Capability.Action.literals`, so adding a host action cannot
|
|
55
|
-
* silently omit it from MCP tools, and it is frozen
|
|
56
|
-
*
|
|
55
|
+
* silently omit it from MCP tools, and it is frozen so no caller can narrow
|
|
56
|
+
* or widen what every tool declares. Each binding records it deduplicated and
|
|
57
|
+
* sorted, as `FlowBinding.make` records every declaration.
|
|
57
58
|
*
|
|
58
59
|
* @category constants
|
|
59
60
|
* @since 1.0.0-rc.0
|
package/dist/esm/McpFlows.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpFlows.js","sourceRoot":"","sources":["../../src/McpFlows.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Projects a connected MCP server's tools as an ordinary {@link FlowBinding.Source}.\n *\n * This is the whole adapter: `@smthrs/harness/FlowBinding`'s own module doc\n * already names the target directly: \"a standard filesystem flow, a memory\n * flow, an incoming MCP tool, a durable child agent\" are all just a flow\n * declaration plus the code that runs it. Nothing about the harness, the\n * registry, or the cell loop needs to know a given flow's implementation\n * happens to proxy a remote MCP `tools/call`; a cell that reads a file and a\n * cell that calls an MCP tool run the identical two lines.\n *\n * @since 1.0.0-rc.0\n */\n\nimport * as Capability from \"@smthrs/capability/Capability\"\nimport * as Effects from \"@smthrs/core/Effects\"\nimport * as FlowBinding from \"@smthrs/harness/FlowBinding\"\nimport { Effect, Exit, Schema, Scope } from \"effect\"\nimport * as McpClient from \"./McpClient.ts\"\nimport { McpError } from \"./McpError.ts\"\n\n/**\n * Decoded input accepted by every MCP tool flow, which is whatever the remote\n * tool's own JSON Schema describes. The registry still discloses the real parameter\n * shape, as shown by {@link toolBinding}. This is only the runtime decode, and it\n * is permissive because the server, not this adapter, owns validation.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Args = Schema.Record(Schema.String, Schema.Unknown)\n\n/**\n * Decoded output returned by every MCP tool flow, carrying the tool's content\n * blocks by shape plus whether the server reported an error.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Result = Schema.Struct({\n content: Schema.Array(Schema.Record(Schema.String, Schema.Unknown)),\n isError: Schema.Boolean,\n structuredContent: Schema.optional(Schema.Record(Schema.String, Schema.Unknown))\n})\n\n/**\n * The authority every MCP tool flow declares.\n *\n * An MCP tool is opaque code this adapter does not control, the same\n * situation `@smthrs/registry/MarkdownFlow` calls \"unprojectable authority\"\n * for a skill with no declared `capabilities`: the honest declaration is\n * everything, not a guess.\n *\n * It is spelled as one exact `namespace:operation:resource` per action because\n * the cell boundary reads each declaration with `Capability.parse`, which\n * rejects anything that does not have exactly those three colon-separated\n * components. An unparseable declaration counts as unauthorized. The list is\n * derived from `Capability.Action.literals`, so adding a host action cannot\n * silently omit it from MCP tools, and it is frozen because every binding\n * shares this reference.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const capabilities: ReadonlyArray<string> = Object.freeze(\n Capability.Action.literals.map((action) => `${action}:**`)\n)\n\n/**\n * The conservative effect envelope every MCP tool flow declares.\n *\n * @category effects\n * @since 1.0.0-rc.0\n */\nexport const effects = Effects.make({\n reads: [\"**\"],\n writes: [\"**\"],\n mode: \"expected\",\n onConflict: \"serialize\",\n tier: \"irreversible\"\n})\n\n/**\n * Selects and names the tools projected from one MCP catalog.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface ProjectionOptions {\n /** Exact tool names to project. Omitted or empty means every tool. */\n readonly include?: ReadonlyArray<string> | undefined\n /** Exact tool names to drop, applied after `include`. */\n readonly exclude?: ReadonlyArray<string> | undefined\n /** Replaces the default `mcp/<server>` flow-name prefix. */\n readonly namePrefix?: string | undefined\n}\n\n/** One remote tool, bound to a flow name scoped by server so two servers may reuse a tool name. */\nconst toolBinding = (\n client: McpClient.McpClient,\n tool: McpClient.ToolDescription,\n prefix: string\n): FlowBinding.Binding => {\n const toolName = tool.name\n return FlowBinding.make({\n flow: {\n name: `${prefix}/${toolName}`,\n // The server authors this text, so it is attributed as remote content\n // rather than read as if the host had written it. The client bounds it.\n description: tool.description === undefined\n ? `MCP tool \"${toolName}\" on server \"${client.server}\"`\n : `MCP tool \"${toolName}\" on server \"${client.server}\". Server-supplied description: ${tool.description}`,\n capabilities,\n effects,\n input: Args,\n output: Result\n },\n // The server's own JSON Schema document, carried by value so a caller\n // reading `ctx.flows` sees the real parameter shape rather than `Args`'s\n // permissive record type.\n inputDocument: tool.inputSchema as Schema.Json,\n // McpClient authors these messages with remote/process diagnostics withheld.\n publicError: (error: McpError) => error.message,\n handler: (input): Effect.Effect<typeof Result.Type, McpError> =>\n Effect.map(client.callTool(toolName, input), (result) =>\n result.structuredContent === undefined\n ? { content: result.content, isError: result.isError }\n : {\n content: result.content,\n isError: result.isError,\n structuredContent: result.structuredContent\n })\n })\n}\n\n/**\n * Projects an already-connected MCP session's tool catalog as a\n * {@link FlowBinding.Source}, one flow per tool.\n *\n * The client is a precondition, not a parameter this constructor resolves:\n * connecting is a scoped effect (it owns a subprocess), and a `Source` is not\n * scoped, so the host composes {@link McpClient.connect} once, at the same\n * place it composes every other scoped kernel service, and passes the live\n * client here.\n *\n * This constructor is total: it applies exact filters to the catalog it is\n * given. Use {@link connected} when unknown `include` names and an empty\n * `namePrefix` must fail loudly against a freshly fetched catalog.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const mcp = (client: McpClient.McpClient, options: ProjectionOptions = {}): FlowBinding.Source => {\n const prefix = options.namePrefix ?? `mcp/${client.server}`\n const include = options.include === undefined || options.include.length === 0\n ? undefined\n : new Set(options.include)\n const exclude = new Set(options.exclude ?? [])\n const tools = client.tools.filter((tool) =>\n (include === undefined || include.has(tool.name)) && !exclude.has(tool.name)\n )\n return FlowBinding.source(prefix, tools.map((tool) => toolBinding(client, tool, prefix)))\n}\n\n/**\n * Connects to an MCP server and projects its tools in one step.\n *\n * This is the checked entry point: it validates projection options against\n * the freshly fetched catalog before constructing the source. An empty prefix\n * fails before spawning. Failed or interrupted setup, including projection\n * validation, releases the connection before returning to the caller.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const connected = <O extends McpClient.ConnectOptions>(\n options: O & ProjectionOptions\n): Effect.Effect<FlowBinding.Source, McpError, McpClient.Requirements<O> | Scope.Scope> =>\n Effect.gen(function*() {\n if (options.namePrefix === \"\") {\n return yield* Effect.fail(\n new McpError({\n code: \"protocol_error\",\n message: `MCP server \"${options.server}\" option \"namePrefix\" must not be empty`,\n server: options.server\n })\n )\n }\n return yield* Effect.acquireUseRelease(\n Effect.flatMap(Effect.scope, Scope.fork),\n (scope) =>\n Effect.gen(function*() {\n const client = yield* McpClient.connect(options)\n const offered = new Set(client.tools.map((tool) => tool.name))\n const missing = options.include?.find((name) => !offered.has(name))\n if (missing !== undefined) {\n return yield* Effect.fail(\n new McpError({\n code: \"tool_not_found\",\n message: `MCP server \"${client.server}\" offers no requested include tool`,\n server: client.server\n })\n )\n }\n return mcp(client, options)\n }).pipe(Scope.provide(scope)),\n // Projection rejection must release the successfully initialized client.\n (scope, exit) => Exit.isFailure(exit) ? Scope.close(scope, exit) : Effect.void\n )\n })\n"]}
|
|
1
|
+
{"version":3,"file":"McpFlows.js","sourceRoot":"","sources":["../../src/McpFlows.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Projects a connected MCP server's tools as an ordinary {@link FlowBinding.Source}.\n *\n * This is the whole adapter: `@smthrs/harness/FlowBinding`'s own module doc\n * already names the target directly: \"a standard filesystem flow, a memory\n * flow, an incoming MCP tool, a durable child agent\" are all just a flow\n * declaration plus the code that runs it. Nothing about the harness, the\n * registry, or the cell loop needs to know a given flow's implementation\n * happens to proxy a remote MCP `tools/call`; a cell that reads a file and a\n * cell that calls an MCP tool run the identical two lines.\n *\n * @since 1.0.0-rc.0\n */\n\nimport * as Capability from \"@smthrs/capability/Capability\"\nimport * as Effects from \"@smthrs/core/Effects\"\nimport * as FlowBinding from \"@smthrs/harness/FlowBinding\"\nimport { Effect, Exit, Schema, Scope } from \"effect\"\nimport * as McpClient from \"./McpClient.ts\"\nimport { McpError } from \"./McpError.ts\"\n\n/**\n * Decoded input accepted by every MCP tool flow, which is whatever the remote\n * tool's own JSON Schema describes. The registry still discloses the real parameter\n * shape, as shown by {@link toolBinding}. This is only the runtime decode, and it\n * is permissive because the server, not this adapter, owns validation.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Args = Schema.Record(Schema.String, Schema.Unknown)\n\n/**\n * Decoded output returned by every MCP tool flow, carrying the tool's content\n * blocks by shape plus whether the server reported an error.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n */\nexport const Result = Schema.Struct({\n content: Schema.Array(Schema.Record(Schema.String, Schema.Unknown)),\n isError: Schema.Boolean,\n structuredContent: Schema.optional(Schema.Record(Schema.String, Schema.Unknown))\n})\n\n/**\n * The authority every MCP tool flow declares.\n *\n * An MCP tool is opaque code this adapter does not control, the same\n * situation `@smthrs/registry/MarkdownFlow` calls \"unprojectable authority\"\n * for a skill with no declared `capabilities`: the honest declaration is\n * everything, not a guess.\n *\n * It is spelled as one exact `namespace:operation:resource` per action because\n * the cell boundary reads each declaration with `Capability.parse`, which\n * rejects anything that does not have exactly those three colon-separated\n * components. An unparseable declaration counts as unauthorized. The list is\n * derived from `Capability.Action.literals`, so adding a host action cannot\n * silently omit it from MCP tools, and it is frozen so no caller can narrow\n * or widen what every tool declares. Each binding records it deduplicated and\n * sorted, as `FlowBinding.make` records every declaration.\n *\n * @category constants\n * @since 1.0.0-rc.0\n */\nexport const capabilities: ReadonlyArray<string> = Object.freeze(\n Capability.Action.literals.map((action) => `${action}:**`)\n)\n\n/**\n * The conservative effect envelope every MCP tool flow declares.\n *\n * @category effects\n * @since 1.0.0-rc.0\n */\nexport const effects = Effects.make({\n reads: [\"**\"],\n writes: [\"**\"],\n mode: \"expected\",\n onConflict: \"serialize\",\n tier: \"irreversible\"\n})\n\n/**\n * Selects and names the tools projected from one MCP catalog.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport interface ProjectionOptions {\n /** Exact tool names to project. Omitted or empty means every tool. */\n readonly include?: ReadonlyArray<string> | undefined\n /** Exact tool names to drop, applied after `include`. */\n readonly exclude?: ReadonlyArray<string> | undefined\n /** Replaces the default `mcp/<server>` flow-name prefix. */\n readonly namePrefix?: string | undefined\n}\n\n/** One remote tool, bound to a flow name scoped by server so two servers may reuse a tool name. */\nconst toolBinding = (\n client: McpClient.McpClient,\n tool: McpClient.ToolDescription,\n prefix: string\n): FlowBinding.Binding => {\n const toolName = tool.name\n return FlowBinding.make({\n flow: {\n name: `${prefix}/${toolName}`,\n // The server authors this text, so it is attributed as remote content\n // rather than read as if the host had written it. The client bounds it.\n description: tool.description === undefined\n ? `MCP tool \"${toolName}\" on server \"${client.server}\"`\n : `MCP tool \"${toolName}\" on server \"${client.server}\". Server-supplied description: ${tool.description}`,\n capabilities,\n effects,\n input: Args,\n output: Result\n },\n // The server's own JSON Schema document, carried by value so a caller\n // reading `ctx.flows` sees the real parameter shape rather than `Args`'s\n // permissive record type.\n inputDocument: tool.inputSchema as Schema.Json,\n // McpClient authors these messages with remote/process diagnostics withheld.\n publicError: (error: McpError) => error.message,\n handler: (input): Effect.Effect<typeof Result.Type, McpError> =>\n Effect.map(client.callTool(toolName, input), (result) =>\n result.structuredContent === undefined\n ? { content: result.content, isError: result.isError }\n : {\n content: result.content,\n isError: result.isError,\n structuredContent: result.structuredContent\n })\n })\n}\n\n/**\n * Projects an already-connected MCP session's tool catalog as a\n * {@link FlowBinding.Source}, one flow per tool.\n *\n * The client is a precondition, not a parameter this constructor resolves:\n * connecting is a scoped effect (it owns a subprocess), and a `Source` is not\n * scoped, so the host composes {@link McpClient.connect} once, at the same\n * place it composes every other scoped kernel service, and passes the live\n * client here.\n *\n * This constructor is total: it applies exact filters to the catalog it is\n * given. Use {@link connected} when unknown `include` names and an empty\n * `namePrefix` must fail loudly against a freshly fetched catalog.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const mcp = (client: McpClient.McpClient, options: ProjectionOptions = {}): FlowBinding.Source => {\n const prefix = options.namePrefix ?? `mcp/${client.server}`\n const include = options.include === undefined || options.include.length === 0\n ? undefined\n : new Set(options.include)\n const exclude = new Set(options.exclude ?? [])\n const tools = client.tools.filter((tool) =>\n (include === undefined || include.has(tool.name)) && !exclude.has(tool.name)\n )\n return FlowBinding.source(prefix, tools.map((tool) => toolBinding(client, tool, prefix)))\n}\n\n/**\n * Connects to an MCP server and projects its tools in one step.\n *\n * This is the checked entry point: it validates projection options against\n * the freshly fetched catalog before constructing the source. An empty prefix\n * fails before spawning. Failed or interrupted setup, including projection\n * validation, releases the connection before returning to the caller.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const connected = <O extends McpClient.ConnectOptions>(\n options: O & ProjectionOptions\n): Effect.Effect<FlowBinding.Source, McpError, McpClient.Requirements<O> | Scope.Scope> =>\n Effect.gen(function*() {\n if (options.namePrefix === \"\") {\n return yield* Effect.fail(\n new McpError({\n code: \"protocol_error\",\n message: `MCP server \"${options.server}\" option \"namePrefix\" must not be empty`,\n server: options.server\n })\n )\n }\n return yield* Effect.acquireUseRelease(\n Effect.flatMap(Effect.scope, Scope.fork),\n (scope) =>\n Effect.gen(function*() {\n const client = yield* McpClient.connect(options)\n const offered = new Set(client.tools.map((tool) => tool.name))\n const missing = options.include?.find((name) => !offered.has(name))\n if (missing !== undefined) {\n return yield* Effect.fail(\n new McpError({\n code: \"tool_not_found\",\n message: `MCP server \"${client.server}\" offers no requested include tool`,\n server: client.server\n })\n )\n }\n return mcp(client, options)\n }).pipe(Scope.provide(scope)),\n // Projection rejection must release the successfully initialized client.\n (scope, exit) => Exit.isFailure(exit) ? Scope.close(scope, exit) : Effect.void\n )\n })\n"]}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@smthrs/mcp",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "1.0.0-rc.
|
|
5
|
+
"version": "1.0.0-rc.4",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"smthrs": {
|
|
8
8
|
"group": "agent"
|
|
@@ -116,20 +116,20 @@
|
|
|
116
116
|
"tag": "next"
|
|
117
117
|
},
|
|
118
118
|
"dependencies": {
|
|
119
|
-
"@smthrs/canonical": "1.0.0-rc.
|
|
120
|
-
"@smthrs/capability": "1.0.0-rc.
|
|
121
|
-
"@smthrs/core": "1.0.0-rc.
|
|
122
|
-
"@smthrs/harness": "1.0.0-rc.
|
|
123
|
-
"@smthrs/journal": "1.0.0-rc.
|
|
124
|
-
"@smthrs/kernel": "1.0.0-rc.
|
|
119
|
+
"@smthrs/canonical": "1.0.0-rc.4",
|
|
120
|
+
"@smthrs/capability": "1.0.0-rc.4",
|
|
121
|
+
"@smthrs/core": "1.0.0-rc.4",
|
|
122
|
+
"@smthrs/harness": "1.0.0-rc.4",
|
|
123
|
+
"@smthrs/journal": "1.0.0-rc.4",
|
|
124
|
+
"@smthrs/kernel": "1.0.0-rc.4"
|
|
125
125
|
},
|
|
126
126
|
"devDependencies": {
|
|
127
127
|
"@effect/language-service": "0.87.2",
|
|
128
128
|
"@effect/platform-node": "4.0.0-rc.115",
|
|
129
129
|
"@effect/vitest": "4.0.0-rc.115",
|
|
130
130
|
"@eslint/js": "9.39.5",
|
|
131
|
-
"@smthrs/model": "1.0.0-rc.
|
|
132
|
-
"@smthrs/registry": "1.0.0-rc.
|
|
131
|
+
"@smthrs/model": "1.0.0-rc.4",
|
|
132
|
+
"@smthrs/registry": "1.0.0-rc.4",
|
|
133
133
|
"@types/node": "26.4.1",
|
|
134
134
|
"@vitest/coverage-v8": "5.0.0",
|
|
135
135
|
"dprint": "0.57.1",
|
package/src/McpClient.ts
CHANGED
|
@@ -223,7 +223,7 @@ export const HttpConnectOptionsSchema = Schema.Struct({
|
|
|
223
223
|
*/
|
|
224
224
|
export const clientInfo: { readonly name: string; readonly version: string } = Object.freeze({
|
|
225
225
|
name: "smithers",
|
|
226
|
-
version: "1.0.0-rc.
|
|
226
|
+
version: "1.0.0-rc.4"
|
|
227
227
|
})
|
|
228
228
|
|
|
229
229
|
/**
|
package/src/McpFlows.ts
CHANGED
|
@@ -56,8 +56,9 @@ export const Result = Schema.Struct({
|
|
|
56
56
|
* rejects anything that does not have exactly those three colon-separated
|
|
57
57
|
* components. An unparseable declaration counts as unauthorized. The list is
|
|
58
58
|
* derived from `Capability.Action.literals`, so adding a host action cannot
|
|
59
|
-
* silently omit it from MCP tools, and it is frozen
|
|
60
|
-
*
|
|
59
|
+
* silently omit it from MCP tools, and it is frozen so no caller can narrow
|
|
60
|
+
* or widen what every tool declares. Each binding records it deduplicated and
|
|
61
|
+
* sorted, as `FlowBinding.make` records every declaration.
|
|
61
62
|
*
|
|
62
63
|
* @category constants
|
|
63
64
|
* @since 1.0.0-rc.0
|