effect 4.0.4 → 4.0.6
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/ai-docs/package.json +1 -1
- package/ai-docs/src/06_schedule/10_schedules.ts +5 -4
- package/ai-docs/src/52_graphql/10_basics.ts +19 -13
- package/ai-docs/src/52_graphql/30_batching.ts +6 -4
- package/ai-docs/src/52_graphql/40_aliased-batching.ts +6 -4
- package/ai-docs/tsconfig.json +3 -1
- package/dist/Array.d.ts +207 -58
- package/dist/Array.d.ts.map +1 -1
- package/dist/Array.js +45 -22
- package/dist/Array.js.map +1 -1
- package/dist/Bytes.d.ts +79 -0
- package/dist/Bytes.d.ts.map +1 -0
- package/dist/Bytes.js +109 -0
- package/dist/Bytes.js.map +1 -0
- package/dist/Channel.d.ts +187 -14
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +142 -33
- package/dist/Channel.js.map +1 -1
- package/dist/ChannelSchema.d.ts.map +1 -1
- package/dist/ChannelSchema.js.map +1 -1
- package/dist/Chunk.d.ts +39 -21
- package/dist/Chunk.d.ts.map +1 -1
- package/dist/Chunk.js +26 -17
- package/dist/Chunk.js.map +1 -1
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js +8 -3
- package/dist/Config.js.map +1 -1
- package/dist/ConfigProvider.d.ts.map +1 -1
- package/dist/ConfigProvider.js +34 -32
- package/dist/ConfigProvider.js.map +1 -1
- package/dist/Cron.d.ts +2 -2
- package/dist/Cron.d.ts.map +1 -1
- package/dist/Cron.js +6 -3
- package/dist/Cron.js.map +1 -1
- package/dist/Duration.d.ts.map +1 -1
- package/dist/Duration.js +58 -21
- package/dist/Duration.js.map +1 -1
- package/dist/Effect.d.ts +548 -182
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +261 -76
- package/dist/Effect.js.map +1 -1
- package/dist/Equivalence.d.ts +2 -1
- package/dist/Equivalence.d.ts.map +1 -1
- package/dist/Equivalence.js +12 -8
- package/dist/Equivalence.js.map +1 -1
- package/dist/Exit.d.ts +24 -9
- package/dist/Exit.d.ts.map +1 -1
- package/dist/Exit.js +8 -3
- package/dist/Exit.js.map +1 -1
- package/dist/FiberHandle.d.ts +2 -0
- package/dist/FiberHandle.d.ts.map +1 -1
- package/dist/FiberHandle.js +9 -4
- package/dist/FiberHandle.js.map +1 -1
- package/dist/FiberMap.d.ts +2 -0
- package/dist/FiberMap.d.ts.map +1 -1
- package/dist/FiberMap.js +5 -2
- package/dist/FiberMap.js.map +1 -1
- package/dist/FileSystem.d.ts +28 -9
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js +3 -0
- package/dist/FileSystem.js.map +1 -1
- package/dist/Graph.d.ts.map +1 -1
- package/dist/Graph.js.map +1 -1
- package/dist/HashSet.d.ts.map +1 -1
- package/dist/HashSet.js.map +1 -1
- package/dist/Iterable.d.ts.map +1 -1
- package/dist/Iterable.js +18 -17
- package/dist/Iterable.js.map +1 -1
- package/dist/JsonSchema.d.ts +9 -3
- package/dist/JsonSchema.d.ts.map +1 -1
- package/dist/JsonSchema.js +19 -3
- package/dist/JsonSchema.js.map +1 -1
- package/dist/Layer.d.ts.map +1 -1
- package/dist/Layer.js +2 -2
- package/dist/Layer.js.map +1 -1
- package/dist/ManagedRuntime.d.ts +19 -1
- package/dist/ManagedRuntime.d.ts.map +1 -1
- package/dist/ManagedRuntime.js +62 -6
- package/dist/ManagedRuntime.js.map +1 -1
- package/dist/Match.d.ts +20 -6
- package/dist/Match.d.ts.map +1 -1
- package/dist/Match.js +2 -2
- package/dist/Match.js.map +1 -1
- package/dist/Metric.d.ts +132 -0
- package/dist/Metric.d.ts.map +1 -1
- package/dist/Metric.js +197 -25
- package/dist/Metric.js.map +1 -1
- package/dist/MutableHashMap.d.ts.map +1 -1
- package/dist/MutableHashMap.js.map +1 -1
- package/dist/Number.js +2 -2
- package/dist/Number.js.map +1 -1
- package/dist/Optic.d.ts.map +1 -1
- package/dist/Optic.js.map +1 -1
- package/dist/Path.d.ts +37 -5
- package/dist/Path.d.ts.map +1 -1
- package/dist/Path.js +44 -6
- package/dist/Path.js.map +1 -1
- package/dist/PubSub.d.ts.map +1 -1
- package/dist/PubSub.js +12 -7
- package/dist/PubSub.js.map +1 -1
- package/dist/Queue.d.ts +4 -1
- package/dist/Queue.d.ts.map +1 -1
- package/dist/Queue.js +4 -1
- package/dist/Queue.js.map +1 -1
- package/dist/Random.d.ts.map +1 -1
- package/dist/Random.js +1 -1
- package/dist/Random.js.map +1 -1
- package/dist/RcMap.d.ts +12 -7
- package/dist/RcMap.d.ts.map +1 -1
- package/dist/RcMap.js +9 -6
- package/dist/RcMap.js.map +1 -1
- package/dist/Record.d.ts +51 -0
- package/dist/Record.d.ts.map +1 -1
- package/dist/Record.js +17 -0
- package/dist/Record.js.map +1 -1
- package/dist/Ref.d.ts.map +1 -1
- package/dist/Ref.js.map +1 -1
- package/dist/References.d.ts +5 -4
- package/dist/References.d.ts.map +1 -1
- package/dist/References.js +5 -4
- package/dist/References.js.map +1 -1
- package/dist/RequestResolver.d.ts +31 -1
- package/dist/RequestResolver.d.ts.map +1 -1
- package/dist/RequestResolver.js +39 -4
- package/dist/RequestResolver.js.map +1 -1
- package/dist/Resource.js +1 -1
- package/dist/Resource.js.map +1 -1
- package/dist/Runtime.d.ts +3 -3
- package/dist/Runtime.d.ts.map +1 -1
- package/dist/Runtime.js +18 -15
- package/dist/Runtime.js.map +1 -1
- package/dist/Schedule.d.ts.map +1 -1
- package/dist/Schedule.js.map +1 -1
- package/dist/Schema.d.ts +383 -326
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +338 -17
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaAST.d.ts +5 -5
- package/dist/SchemaAST.d.ts.map +1 -1
- package/dist/SchemaAST.js +24 -8
- package/dist/SchemaAST.js.map +1 -1
- package/dist/SchemaGetter.d.ts +8 -3
- package/dist/SchemaGetter.d.ts.map +1 -1
- package/dist/SchemaGetter.js +15 -5
- package/dist/SchemaGetter.js.map +1 -1
- package/dist/SchemaIssue.d.ts +4 -4
- package/dist/SchemaIssue.d.ts.map +1 -1
- package/dist/SchemaIssue.js +29 -51
- package/dist/SchemaIssue.js.map +1 -1
- package/dist/SchemaRepresentation.d.ts +56 -1
- package/dist/SchemaRepresentation.d.ts.map +1 -1
- package/dist/SchemaRepresentation.js +18 -0
- package/dist/SchemaRepresentation.js.map +1 -1
- package/dist/SchemaTransformation.d.ts +1 -1
- package/dist/SchemaTransformation.js +1 -1
- package/dist/Scope.d.ts +12 -2
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +5 -0
- package/dist/Scope.js.map +1 -1
- package/dist/ScopedCache.d.ts +10 -7
- package/dist/ScopedCache.d.ts.map +1 -1
- package/dist/ScopedCache.js +9 -5
- package/dist/ScopedCache.js.map +1 -1
- package/dist/SemVer.d.ts +1196 -0
- package/dist/SemVer.d.ts.map +1 -0
- package/dist/SemVer.js +756 -0
- package/dist/SemVer.js.map +1 -0
- package/dist/SemVerRange.d.ts +559 -0
- package/dist/SemVerRange.d.ts.map +1 -0
- package/dist/SemVerRange.js +551 -0
- package/dist/SemVerRange.js.map +1 -0
- package/dist/Sink.d.ts.map +1 -1
- package/dist/Sink.js +6 -2
- package/dist/Sink.js.map +1 -1
- package/dist/Stream.d.ts +235 -8
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +145 -60
- package/dist/Stream.js.map +1 -1
- package/dist/String.d.ts +16 -2
- package/dist/String.d.ts.map +1 -1
- package/dist/String.js +25 -10
- package/dist/String.js.map +1 -1
- package/dist/TextDiff.d.ts +399 -0
- package/dist/TextDiff.d.ts.map +1 -0
- package/dist/TextDiff.js +634 -0
- package/dist/TextDiff.js.map +1 -0
- package/dist/TxHashMap.d.ts.map +1 -1
- package/dist/TxHashMap.js.map +1 -1
- package/dist/TxHashSet.d.ts.map +1 -1
- package/dist/TxHashSet.js.map +1 -1
- package/dist/TxRef.d.ts.map +1 -1
- package/dist/TxRef.js +3 -2
- package/dist/TxRef.js.map +1 -1
- package/dist/ai/AiError.d.ts +78 -14
- package/dist/ai/AiError.d.ts.map +1 -1
- package/dist/ai/AiError.js +51 -3
- package/dist/ai/AiError.js.map +1 -1
- package/dist/ai/Chat.d.ts +1 -2
- package/dist/ai/Chat.d.ts.map +1 -1
- package/dist/ai/Chat.js +6 -3
- package/dist/ai/Chat.js.map +1 -1
- package/dist/ai/Decision.d.ts +116 -20
- package/dist/ai/Decision.d.ts.map +1 -1
- package/dist/ai/Decision.js +37 -3
- package/dist/ai/Decision.js.map +1 -1
- package/dist/ai/DecisionModel.d.ts +129 -11
- package/dist/ai/DecisionModel.d.ts.map +1 -1
- package/dist/ai/DecisionModel.js +183 -95
- package/dist/ai/DecisionModel.js.map +1 -1
- package/dist/ai/EmbeddingModel.d.ts +10 -0
- package/dist/ai/EmbeddingModel.d.ts.map +1 -1
- package/dist/ai/EmbeddingModel.js +21 -7
- package/dist/ai/EmbeddingModel.js.map +1 -1
- package/dist/ai/LanguageModel.d.ts.map +1 -1
- package/dist/ai/LanguageModel.js +47 -35
- package/dist/ai/LanguageModel.js.map +1 -1
- package/dist/ai/McpClient.d.ts +289 -0
- package/dist/ai/McpClient.d.ts.map +1 -0
- package/dist/ai/McpClient.js +819 -0
- package/dist/ai/McpClient.js.map +1 -0
- package/dist/ai/McpClientError.d.ts +254 -0
- package/dist/ai/McpClientError.d.ts.map +1 -0
- package/dist/ai/McpClientError.js +260 -0
- package/dist/ai/McpClientError.js.map +1 -0
- package/dist/ai/McpProtocol.d.ts +2 -2
- package/dist/ai/McpProtocol.d.ts.map +1 -1
- package/dist/ai/McpSchema.d.ts +368 -235
- package/dist/ai/McpSchema.d.ts.map +1 -1
- package/dist/ai/McpSchema.js +94 -24
- package/dist/ai/McpSchema.js.map +1 -1
- package/dist/ai/McpServer.d.ts +6 -52
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +27 -50
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/Prompt.d.ts +22 -20
- package/dist/ai/Prompt.d.ts.map +1 -1
- package/dist/ai/Prompt.js +23 -1
- package/dist/ai/Prompt.js.map +1 -1
- package/dist/ai/Response.d.ts +148 -4
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js +35 -37
- package/dist/ai/Response.js.map +1 -1
- package/dist/ai/Tool.d.ts +12 -4
- package/dist/ai/Tool.d.ts.map +1 -1
- package/dist/ai/Tool.js.map +1 -1
- package/dist/ai/Toolkit.d.ts +48 -1
- package/dist/ai/Toolkit.d.ts.map +1 -1
- package/dist/ai/Toolkit.js +65 -12
- package/dist/ai/Toolkit.js.map +1 -1
- package/dist/ai/index.d.ts +10 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +10 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/internal/mcpCore.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js +1 -1
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js +2 -2
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js +2 -2
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js +4 -7
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
- package/dist/ai/internal/mcpProtocol.js +16 -2
- package/dist/ai/internal/mcpProtocol.js.map +1 -1
- package/dist/ai/internal/mcpRuntime.js +3 -4
- package/dist/ai/internal/mcpRuntime.js.map +1 -1
- package/dist/ai/internal/mcpSchema/v2024_11_05.js +19 -13
- package/dist/ai/internal/mcpSchema/v2024_11_05.js.map +1 -1
- package/dist/ai/internal/mcpSchema/v2025_03_26.js +3 -2
- package/dist/ai/internal/mcpSchema/v2025_03_26.js.map +1 -1
- package/dist/ai/internal/mcpSchema/v2025_06_18.js +7 -7
- package/dist/ai/internal/mcpSchema/v2025_06_18.js.map +1 -1
- package/dist/ai/internal/mcpSchema/v2025_11_25.js +8 -8
- package/dist/ai/internal/mcpSchema/v2025_11_25.js.map +1 -1
- package/dist/ai/internal/mcpSchema/v2026_07_28.js +43 -42
- package/dist/ai/internal/mcpSchema/v2026_07_28.js.map +1 -1
- package/dist/cli/CliError.d.ts +42 -2
- package/dist/cli/CliError.d.ts.map +1 -1
- package/dist/cli/CliError.js +44 -5
- package/dist/cli/CliError.js.map +1 -1
- package/dist/cli/Command.d.ts +286 -2
- package/dist/cli/Command.d.ts.map +1 -1
- package/dist/cli/Command.js +107 -6
- package/dist/cli/Command.js.map +1 -1
- package/dist/cli/Completions.d.ts +10 -0
- package/dist/cli/Completions.d.ts.map +1 -1
- package/dist/cli/Completions.js.map +1 -1
- package/dist/cli/Flag.d.ts +215 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +89 -0
- package/dist/cli/Flag.js.map +1 -1
- package/dist/cli/GlobalFlag.d.ts.map +1 -1
- package/dist/cli/GlobalFlag.js +3 -3
- package/dist/cli/GlobalFlag.js.map +1 -1
- package/dist/cli/Param.d.ts +194 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +86 -0
- package/dist/cli/Param.js.map +1 -1
- package/dist/cli/TerminalCapabilities.d.ts +84 -0
- package/dist/cli/TerminalCapabilities.d.ts.map +1 -0
- package/dist/cli/TerminalCapabilities.js +122 -0
- package/dist/cli/TerminalCapabilities.js.map +1 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +5 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/internal/command.d.ts +2 -1
- package/dist/cli/internal/command.d.ts.map +1 -1
- package/dist/cli/internal/command.js +7 -3
- package/dist/cli/internal/command.js.map +1 -1
- package/dist/cli/internal/completions/bash.js +7 -5
- package/dist/cli/internal/completions/bash.js.map +1 -1
- package/dist/cli/internal/completions/descriptor.js +16 -1
- package/dist/cli/internal/completions/descriptor.js.map +1 -1
- package/dist/cli/internal/completions/fish.js +12 -10
- package/dist/cli/internal/completions/fish.js.map +1 -1
- package/dist/cli/internal/completions/powershell.js +20 -10
- package/dist/cli/internal/completions/powershell.js.map +1 -1
- package/dist/cli/internal/completions/zsh.js +15 -8
- package/dist/cli/internal/completions/zsh.js.map +1 -1
- package/dist/cli/internal/formatter.d.ts +2 -0
- package/dist/cli/internal/formatter.d.ts.map +1 -0
- package/dist/cli/internal/formatter.js +15 -0
- package/dist/cli/internal/formatter.js.map +1 -0
- package/dist/cli/internal/lexer.js +24 -10
- package/dist/cli/internal/lexer.js.map +1 -1
- package/dist/cli/internal/parser.js +35 -15
- package/dist/cli/internal/parser.js.map +1 -1
- package/dist/cli/internal/wizard.d.ts.map +1 -1
- package/dist/cli/internal/wizard.js +2 -1
- package/dist/cli/internal/wizard.js.map +1 -1
- package/dist/cluster/ClusterCron.d.ts +29 -1
- package/dist/cluster/ClusterCron.d.ts.map +1 -1
- package/dist/cluster/ClusterCron.js +64 -32
- package/dist/cluster/ClusterCron.js.map +1 -1
- package/dist/cluster/ClusterMetrics.d.ts +143 -7
- package/dist/cluster/ClusterMetrics.d.ts.map +1 -1
- package/dist/cluster/ClusterMetrics.js +151 -7
- package/dist/cluster/ClusterMetrics.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts +2 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +98 -18
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/Entity.d.ts +2 -0
- package/dist/cluster/Entity.d.ts.map +1 -1
- package/dist/cluster/Entity.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts +21 -0
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +20 -12
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Runners.d.ts.map +1 -1
- package/dist/cluster/Runners.js +96 -37
- package/dist/cluster/Runners.js.map +1 -1
- package/dist/cluster/Sharding.d.ts +1 -0
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +95 -32
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/ShardingConfig.d.ts +20 -0
- package/dist/cluster/ShardingConfig.d.ts.map +1 -1
- package/dist/cluster/ShardingConfig.js +4 -0
- package/dist/cluster/ShardingConfig.js.map +1 -1
- package/dist/cluster/SqlMessageStorage.d.ts.map +1 -1
- package/dist/cluster/SqlMessageStorage.js +40 -50
- package/dist/cluster/SqlMessageStorage.js.map +1 -1
- package/dist/cluster/SqlRunnerStorage.d.ts +2 -2
- package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
- package/dist/cluster/SqlRunnerStorage.js +10 -4
- package/dist/cluster/SqlRunnerStorage.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +66 -9
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/devtools/DevTools.d.ts +3 -2
- package/dist/devtools/DevTools.d.ts.map +1 -1
- package/dist/devtools/DevTools.js +3 -2
- package/dist/devtools/DevTools.js.map +1 -1
- package/dist/devtools/DevToolsClient.d.ts +11 -0
- package/dist/devtools/DevToolsClient.d.ts.map +1 -1
- package/dist/devtools/DevToolsClient.js +31 -4
- package/dist/devtools/DevToolsClient.js.map +1 -1
- package/dist/encoding/Base64Url.d.ts +29 -0
- package/dist/encoding/Base64Url.d.ts.map +1 -1
- package/dist/encoding/Base64Url.js +29 -0
- package/dist/encoding/Base64Url.js.map +1 -1
- package/dist/encoding/Ini.d.ts.map +1 -1
- package/dist/encoding/Ini.js +3 -0
- package/dist/encoding/Ini.js.map +1 -1
- package/dist/encoding/JsonArray.d.ts +270 -0
- package/dist/encoding/JsonArray.d.ts.map +1 -0
- package/dist/encoding/JsonArray.js +691 -0
- package/dist/encoding/JsonArray.js.map +1 -0
- package/dist/encoding/Ndjson.d.ts +43 -4
- package/dist/encoding/Ndjson.d.ts.map +1 -1
- package/dist/encoding/Ndjson.js +169 -18
- package/dist/encoding/Ndjson.js.map +1 -1
- package/dist/encoding/SchemaBinary.d.ts +9 -1
- package/dist/encoding/SchemaBinary.d.ts.map +1 -1
- package/dist/encoding/SchemaBinary.js +12 -19
- package/dist/encoding/SchemaBinary.js.map +1 -1
- package/dist/encoding/Sse.js +1 -1
- package/dist/encoding/Sse.js.map +1 -1
- package/dist/encoding/Tar.d.ts +309 -0
- package/dist/encoding/Tar.d.ts.map +1 -0
- package/dist/encoding/Tar.js +1182 -0
- package/dist/encoding/Tar.js.map +1 -0
- package/dist/encoding/Toml.js +3 -3
- package/dist/encoding/Toml.js.map +1 -1
- package/dist/encoding/Xml.d.ts +464 -0
- package/dist/encoding/Xml.d.ts.map +1 -0
- package/dist/encoding/Xml.js +1619 -0
- package/dist/encoding/Xml.js.map +1 -0
- package/dist/encoding/Yaml.d.ts +6 -2
- package/dist/encoding/Yaml.d.ts.map +1 -1
- package/dist/encoding/Yaml.js +97 -34
- package/dist/encoding/Yaml.js.map +1 -1
- package/dist/encoding/Zip.d.ts +413 -0
- package/dist/encoding/Zip.d.ts.map +1 -0
- package/dist/encoding/Zip.js +1255 -0
- package/dist/encoding/Zip.js.map +1 -0
- package/dist/encoding/index.d.ts +20 -0
- package/dist/encoding/index.d.ts.map +1 -1
- package/dist/encoding/index.js +20 -0
- package/dist/encoding/index.js.map +1 -1
- package/dist/eventlog/EventJournal.d.ts +90 -5
- package/dist/eventlog/EventJournal.d.ts.map +1 -1
- package/dist/eventlog/EventJournal.js +488 -228
- package/dist/eventlog/EventJournal.js.map +1 -1
- package/dist/eventlog/EventLog.d.ts +180 -12
- package/dist/eventlog/EventLog.d.ts.map +1 -1
- package/dist/eventlog/EventLog.js +394 -146
- package/dist/eventlog/EventLog.js.map +1 -1
- package/dist/eventlog/EventLogEncryption.d.ts +36 -30
- package/dist/eventlog/EventLogEncryption.d.ts.map +1 -1
- package/dist/eventlog/EventLogEncryption.js +97 -38
- package/dist/eventlog/EventLogEncryption.js.map +1 -1
- package/dist/eventlog/EventLogMessage.d.ts +74 -34
- package/dist/eventlog/EventLogMessage.d.ts.map +1 -1
- package/dist/eventlog/EventLogMessage.js +45 -11
- package/dist/eventlog/EventLogMessage.js.map +1 -1
- package/dist/eventlog/EventLogRemote.d.ts +45 -8
- package/dist/eventlog/EventLogRemote.d.ts.map +1 -1
- package/dist/eventlog/EventLogRemote.js +51 -14
- package/dist/eventlog/EventLogRemote.js.map +1 -1
- package/dist/eventlog/EventLogServer.d.ts +46 -3
- package/dist/eventlog/EventLogServer.d.ts.map +1 -1
- package/dist/eventlog/EventLogServer.js +119 -19
- package/dist/eventlog/EventLogServer.js.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.d.ts +23 -33
- package/dist/eventlog/EventLogServerEncrypted.d.ts.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.js +97 -70
- package/dist/eventlog/EventLogServerEncrypted.js.map +1 -1
- package/dist/eventlog/EventLogServerUnencrypted.d.ts +39 -5
- package/dist/eventlog/EventLogServerUnencrypted.d.ts.map +1 -1
- package/dist/eventlog/EventLogServerUnencrypted.js +151 -69
- package/dist/eventlog/EventLogServerUnencrypted.js.map +1 -1
- package/dist/eventlog/EventRow.d.ts +288 -0
- package/dist/eventlog/EventRow.d.ts.map +1 -0
- package/dist/eventlog/EventRow.js +435 -0
- package/dist/eventlog/EventRow.js.map +1 -0
- package/dist/eventlog/SqlEventJournal.d.ts +18 -18
- package/dist/eventlog/SqlEventJournal.d.ts.map +1 -1
- package/dist/eventlog/SqlEventJournal.js +387 -159
- package/dist/eventlog/SqlEventJournal.js.map +1 -1
- package/dist/eventlog/SqlEventLogServerEncrypted.d.ts +10 -18
- package/dist/eventlog/SqlEventLogServerEncrypted.d.ts.map +1 -1
- package/dist/eventlog/SqlEventLogServerEncrypted.js +179 -69
- package/dist/eventlog/SqlEventLogServerEncrypted.js.map +1 -1
- package/dist/eventlog/SqlEventLogServerUnencrypted.d.ts +23 -3
- package/dist/eventlog/SqlEventLogServerUnencrypted.d.ts.map +1 -1
- package/dist/eventlog/SqlEventLogServerUnencrypted.js +102 -51
- package/dist/eventlog/SqlEventLogServerUnencrypted.js.map +1 -1
- package/dist/eventlog/index.d.ts +5 -0
- package/dist/eventlog/index.d.ts.map +1 -1
- package/dist/eventlog/index.js +5 -0
- package/dist/eventlog/index.js.map +1 -1
- package/dist/eventlog/internal/conflicts.d.ts +47 -0
- package/dist/eventlog/internal/conflicts.d.ts.map +1 -0
- package/dist/eventlog/internal/conflicts.js +92 -0
- package/dist/eventlog/internal/conflicts.js.map +1 -0
- package/dist/graphql/GraphQLClient.d.ts.map +1 -1
- package/dist/graphql/GraphQLClient.js +12 -5
- package/dist/graphql/GraphQLClient.js.map +1 -1
- package/dist/graphql/GraphQLClientError.d.ts +2 -2
- package/dist/graphql/GraphQLClientError.d.ts.map +1 -1
- package/dist/graphql/GraphQLClientError.js +4 -18
- package/dist/graphql/GraphQLClientError.js.map +1 -1
- package/dist/graphql/GraphQLProtocol.d.ts +252 -11
- package/dist/graphql/GraphQLProtocol.d.ts.map +1 -1
- package/dist/graphql/GraphQLProtocol.js +99 -8
- package/dist/graphql/GraphQLProtocol.js.map +1 -1
- package/dist/graphql/GraphQLResolver.d.ts +3 -1
- package/dist/graphql/GraphQLResolver.d.ts.map +1 -1
- package/dist/graphql/GraphQLResolver.js +91 -19
- package/dist/graphql/GraphQLResolver.js.map +1 -1
- package/dist/http/FetchHttpClient.d.ts +13 -3
- package/dist/http/FetchHttpClient.d.ts.map +1 -1
- package/dist/http/FetchHttpClient.js +56 -6
- package/dist/http/FetchHttpClient.js.map +1 -1
- package/dist/http/FindMyWay/internal/router.js +12 -1
- package/dist/http/FindMyWay/internal/router.js.map +1 -1
- package/dist/http/Headers.d.ts +230 -3
- package/dist/http/Headers.d.ts.map +1 -1
- package/dist/http/Headers.js +267 -5
- package/dist/http/Headers.js.map +1 -1
- package/dist/http/HttpClient.d.ts +105 -0
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +69 -17
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpClientError.d.ts.map +1 -1
- package/dist/http/HttpClientError.js +8 -6
- package/dist/http/HttpClientError.js.map +1 -1
- package/dist/http/HttpClientRequest.d.ts +274 -7
- package/dist/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/http/HttpClientRequest.js +91 -3
- package/dist/http/HttpClientRequest.js.map +1 -1
- package/dist/http/HttpClientResponse.d.ts +53 -0
- package/dist/http/HttpClientResponse.d.ts.map +1 -1
- package/dist/http/HttpClientResponse.js +47 -0
- package/dist/http/HttpClientResponse.js.map +1 -1
- package/dist/http/HttpEffect.d.ts +6 -2
- package/dist/http/HttpEffect.d.ts.map +1 -1
- package/dist/http/HttpEffect.js +21 -17
- package/dist/http/HttpEffect.js.map +1 -1
- package/dist/http/HttpIncomingMessage.d.ts +2 -1
- package/dist/http/HttpIncomingMessage.d.ts.map +1 -1
- package/dist/http/HttpIncomingMessage.js +3 -23
- package/dist/http/HttpIncomingMessage.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts +179 -2
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +226 -18
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpRouter.d.ts.map +1 -1
- package/dist/http/HttpRouter.js +58 -14
- package/dist/http/HttpRouter.js.map +1 -1
- package/dist/http/HttpServerError.d.ts +5 -2
- package/dist/http/HttpServerError.d.ts.map +1 -1
- package/dist/http/HttpServerError.js +11 -7
- package/dist/http/HttpServerError.js.map +1 -1
- package/dist/http/HttpServerRequest.d.ts +25 -5
- package/dist/http/HttpServerRequest.d.ts.map +1 -1
- package/dist/http/HttpServerRequest.js +38 -12
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/HttpServerResponse.d.ts +17 -8
- package/dist/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/http/HttpServerResponse.js +37 -21
- package/dist/http/HttpServerResponse.js.map +1 -1
- package/dist/http/HttpStaticServer.d.ts +0 -12
- package/dist/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/http/HttpStaticServer.js +25 -17
- package/dist/http/HttpStaticServer.js.map +1 -1
- package/dist/http/HttpTraceContext.js +1 -1
- package/dist/http/HttpTraceContext.js.map +1 -1
- package/dist/http/MultipartParser/internal/contentType.d.ts +15 -1
- package/dist/http/MultipartParser/internal/contentType.d.ts.map +1 -1
- package/dist/http/MultipartParser/internal/contentType.js +87 -5
- package/dist/http/MultipartParser/internal/contentType.js.map +1 -1
- package/dist/http/MultipartParser/internal/headers.d.ts.map +1 -1
- package/dist/http/MultipartParser/internal/headers.js +4 -12
- package/dist/http/MultipartParser/internal/headers.js.map +1 -1
- package/dist/http/MultipartParser/internal/multipart.d.ts.map +1 -1
- package/dist/http/MultipartParser/internal/multipart.js +6 -27
- package/dist/http/MultipartParser/internal/multipart.js.map +1 -1
- package/dist/http/Url.d.ts.map +1 -1
- package/dist/http/Url.js +8 -2
- package/dist/http/Url.js.map +1 -1
- package/dist/http/UrlParams.d.ts +112 -8
- package/dist/http/UrlParams.d.ts.map +1 -1
- package/dist/http/UrlParams.js +141 -14
- package/dist/http/UrlParams.js.map +1 -1
- package/dist/http/internal/compression.d.ts +1 -1
- package/dist/http/internal/compression.d.ts.map +1 -1
- package/dist/http/internal/compression.js +2 -10
- package/dist/http/internal/compression.js.map +1 -1
- package/dist/http/internal/compressionBody.d.ts +2 -0
- package/dist/http/internal/compressionBody.d.ts.map +1 -0
- package/dist/http/internal/compressionBody.js +36 -0
- package/dist/http/internal/compressionBody.js.map +1 -0
- package/dist/http/internal/decompression.d.ts +2 -0
- package/dist/http/internal/decompression.d.ts.map +1 -0
- package/dist/http/internal/decompression.js +168 -0
- package/dist/http/internal/decompression.js.map +1 -0
- package/dist/http/internal/lazyStream.d.ts +2 -0
- package/dist/http/internal/lazyStream.d.ts.map +1 -0
- package/dist/http/internal/lazyStream.js +18 -0
- package/dist/http/internal/lazyStream.js.map +1 -0
- package/dist/http/internal/requestState.d.ts +2 -0
- package/dist/http/internal/requestState.d.ts.map +1 -0
- package/dist/http/internal/requestState.js +28 -0
- package/dist/http/internal/requestState.js.map +1 -0
- package/dist/http/internal/tracing.js +14 -4
- package/dist/http/internal/tracing.js.map +1 -1
- package/dist/http/internal/urlParams.d.ts +2 -0
- package/dist/http/internal/urlParams.d.ts.map +1 -0
- package/dist/http/internal/urlParams.js +4 -0
- package/dist/http/internal/urlParams.js.map +1 -0
- package/dist/http/internal/webResponse.d.ts +2 -0
- package/dist/http/internal/webResponse.d.ts.map +1 -0
- package/dist/http/internal/webResponse.js +12 -0
- package/dist/http/internal/webResponse.js.map +1 -0
- package/dist/http-api/HttpApi.js +1 -1
- package/dist/http-api/HttpApi.js.map +1 -1
- package/dist/http-api/HttpApiBuilder.d.ts.map +1 -1
- package/dist/http-api/HttpApiBuilder.js +121 -18
- package/dist/http-api/HttpApiBuilder.js.map +1 -1
- package/dist/http-api/HttpApiClient.d.ts +29 -4
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +85 -24
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/http-api/HttpApiEndpoint.d.ts +55 -29
- package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/http-api/HttpApiEndpoint.js +49 -5
- package/dist/http-api/HttpApiEndpoint.js.map +1 -1
- package/dist/http-api/HttpApiError.d.ts +58 -0
- package/dist/http-api/HttpApiError.d.ts.map +1 -1
- package/dist/http-api/HttpApiError.js +38 -12
- package/dist/http-api/HttpApiError.js.map +1 -1
- package/dist/http-api/HttpApiScalar.d.ts +2 -1
- package/dist/http-api/HttpApiScalar.d.ts.map +1 -1
- package/dist/http-api/HttpApiScalar.js +6 -3
- package/dist/http-api/HttpApiScalar.js.map +1 -1
- package/dist/http-api/HttpApiSchema.d.ts +191 -9
- package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
- package/dist/http-api/HttpApiSchema.js +137 -4
- package/dist/http-api/HttpApiSchema.js.map +1 -1
- package/dist/http-api/HttpApiSwagger.d.ts +5 -0
- package/dist/http-api/HttpApiSwagger.d.ts.map +1 -1
- package/dist/http-api/HttpApiSwagger.js +14 -4
- package/dist/http-api/HttpApiSwagger.js.map +1 -1
- package/dist/http-api/HttpApiTest.d.ts +13 -2
- package/dist/http-api/HttpApiTest.d.ts.map +1 -1
- package/dist/http-api/HttpApiTest.js +30 -9
- package/dist/http-api/HttpApiTest.js.map +1 -1
- package/dist/http-api/OpenApi.d.ts +17 -3
- package/dist/http-api/OpenApi.d.ts.map +1 -1
- package/dist/http-api/OpenApi.js +57 -32
- package/dist/http-api/OpenApi.js.map +1 -1
- package/dist/http-api/internal/path.js +35 -10
- package/dist/http-api/internal/path.js.map +1 -1
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/core.js +18 -2
- package/dist/internal/core.js.map +1 -1
- package/dist/internal/dateTime.js +19 -7
- package/dist/internal/dateTime.js.map +1 -1
- package/dist/internal/effect.js +89 -76
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/graphql.js +12 -2
- package/dist/internal/graphql.js.map +1 -1
- package/dist/internal/hashMap.js +2 -2
- package/dist/internal/hashMap.js.map +1 -1
- package/dist/internal/hydration.d.ts +2 -0
- package/dist/internal/hydration.d.ts.map +1 -0
- package/dist/internal/hydration.js +15 -0
- package/dist/internal/hydration.js.map +1 -0
- package/dist/internal/inflate.d.ts +2 -0
- package/dist/internal/inflate.d.ts.map +1 -0
- package/dist/internal/inflate.js +680 -0
- package/dist/internal/inflate.js.map +1 -0
- package/dist/internal/record.js +6 -0
- package/dist/internal/record.js.map +1 -1
- package/dist/internal/request.js +20 -7
- package/dist/internal/request.js.map +1 -1
- package/dist/internal/schedule.js +17 -22
- package/dist/internal/schedule.js.map +1 -1
- package/dist/internal/schema/fromJsonSchemaDocument.js +136 -126
- package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
- package/dist/internal/schema/interpreter.js +51 -36
- package/dist/internal/schema/interpreter.js.map +1 -1
- package/dist/internal/schema/standardSchema.js +34 -33
- package/dist/internal/schema/standardSchema.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +7 -2
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/schema/toCodec.js +86 -1
- package/dist/internal/schema/toCodec.js.map +1 -1
- package/dist/internal/schema/toFormatter.js +5 -5
- package/dist/internal/schema/toFormatter.js.map +1 -1
- package/dist/internal/schema/toJsonSchemaDocument.js +60 -38
- package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
- package/dist/internal/trie.js +1 -3
- package/dist/internal/trie.js.map +1 -1
- package/dist/internal/uuid.js +7 -3
- package/dist/internal/uuid.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/net/NetAddress.d.ts.map +1 -1
- package/dist/net/NetAddress.js +2 -8
- package/dist/net/NetAddress.js.map +1 -1
- package/dist/observability/Otlp.d.ts +15 -0
- package/dist/observability/Otlp.d.ts.map +1 -1
- package/dist/observability/Otlp.js +3 -0
- package/dist/observability/Otlp.js.map +1 -1
- package/dist/observability/OtlpExporter.d.ts +8 -0
- package/dist/observability/OtlpExporter.d.ts.map +1 -1
- package/dist/observability/OtlpExporter.js +15 -13
- package/dist/observability/OtlpExporter.js.map +1 -1
- package/dist/observability/OtlpLogger.d.ts +17 -0
- package/dist/observability/OtlpLogger.d.ts.map +1 -1
- package/dist/observability/OtlpLogger.js +14 -1
- package/dist/observability/OtlpLogger.js.map +1 -1
- package/dist/observability/OtlpMetrics.d.ts +17 -0
- package/dist/observability/OtlpMetrics.d.ts.map +1 -1
- package/dist/observability/OtlpMetrics.js +18 -3
- package/dist/observability/OtlpMetrics.js.map +1 -1
- package/dist/observability/OtlpResource.d.ts +3 -1
- package/dist/observability/OtlpResource.d.ts.map +1 -1
- package/dist/observability/OtlpResource.js +11 -4
- package/dist/observability/OtlpResource.js.map +1 -1
- package/dist/observability/OtlpSerialization.d.ts +5 -0
- package/dist/observability/OtlpSerialization.d.ts.map +1 -1
- package/dist/observability/OtlpSerialization.js +14 -3
- package/dist/observability/OtlpSerialization.js.map +1 -1
- package/dist/observability/OtlpTracer.d.ts +17 -0
- package/dist/observability/OtlpTracer.d.ts.map +1 -1
- package/dist/observability/OtlpTracer.js +15 -2
- package/dist/observability/OtlpTracer.js.map +1 -1
- package/dist/observability/internal/protobuf.d.ts +0 -9
- package/dist/observability/internal/protobuf.d.ts.map +1 -1
- package/dist/observability/internal/protobuf.js +2 -10
- package/dist/observability/internal/protobuf.js.map +1 -1
- package/dist/persistence/PersistedCache.d.ts.map +1 -1
- package/dist/persistence/PersistedCache.js +1 -1
- package/dist/persistence/PersistedCache.js.map +1 -1
- package/dist/persistence/PersistedQueue.d.ts +6 -2
- package/dist/persistence/PersistedQueue.d.ts.map +1 -1
- package/dist/persistence/PersistedQueue.js +162 -84
- package/dist/persistence/PersistedQueue.js.map +1 -1
- package/dist/persistence/Persistence.d.ts +28 -0
- package/dist/persistence/Persistence.d.ts.map +1 -1
- package/dist/persistence/Persistence.js +36 -8
- package/dist/persistence/Persistence.js.map +1 -1
- package/dist/persistence/RateLimiter.d.ts.map +1 -1
- package/dist/persistence/RateLimiter.js +8 -12
- package/dist/persistence/RateLimiter.js.map +1 -1
- package/dist/persistence/UserDirectories.d.ts +129 -0
- package/dist/persistence/UserDirectories.d.ts.map +1 -0
- package/dist/persistence/UserDirectories.js +178 -0
- package/dist/persistence/UserDirectories.js.map +1 -0
- package/dist/persistence/index.d.ts +5 -0
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +5 -0
- package/dist/persistence/index.js.map +1 -1
- package/dist/process/ChildProcess.d.ts +2 -1
- package/dist/process/ChildProcess.d.ts.map +1 -1
- package/dist/process/ChildProcess.js.map +1 -1
- package/dist/reactivity/AsyncResult.d.ts +6 -0
- package/dist/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/reactivity/AsyncResult.js +28 -1
- package/dist/reactivity/AsyncResult.js.map +1 -1
- package/dist/reactivity/Atom.d.ts +69 -30
- package/dist/reactivity/Atom.d.ts.map +1 -1
- package/dist/reactivity/Atom.js +40 -15
- package/dist/reactivity/Atom.js.map +1 -1
- package/dist/reactivity/AtomHttpApi.d.ts +5 -5
- package/dist/reactivity/AtomHttpApi.d.ts.map +1 -1
- package/dist/reactivity/AtomHttpApi.js +1 -1
- package/dist/reactivity/AtomHttpApi.js.map +1 -1
- package/dist/reactivity/AtomRegistry.d.ts +2 -2
- package/dist/reactivity/AtomRegistry.d.ts.map +1 -1
- package/dist/reactivity/AtomRegistry.js +47 -10
- package/dist/reactivity/AtomRegistry.js.map +1 -1
- package/dist/reactivity/AtomRpc.d.ts +3 -3
- package/dist/reactivity/AtomRpc.d.ts.map +1 -1
- package/dist/reactivity/AtomRpc.js +1 -1
- package/dist/reactivity/AtomRpc.js.map +1 -1
- package/dist/reactivity/Hydration.d.ts.map +1 -1
- package/dist/reactivity/Hydration.js +46 -12
- package/dist/reactivity/Hydration.js.map +1 -1
- package/dist/reactivity/Reactivity.d.ts +71 -7
- package/dist/reactivity/Reactivity.d.ts.map +1 -1
- package/dist/reactivity/Reactivity.js +21 -12
- package/dist/reactivity/Reactivity.js.map +1 -1
- package/dist/rpc/Rpc.d.ts +18 -0
- package/dist/rpc/Rpc.d.ts.map +1 -1
- package/dist/rpc/Rpc.js +20 -0
- package/dist/rpc/Rpc.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts +26 -2
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +202 -61
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcSerialization.d.ts +15 -0
- package/dist/rpc/RpcSerialization.d.ts.map +1 -1
- package/dist/rpc/RpcSerialization.js +21 -5
- package/dist/rpc/RpcSerialization.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +9 -18
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/schema/Model.d.ts +1 -1
- package/dist/schema/VariantSchema.d.ts +22 -3
- package/dist/schema/VariantSchema.d.ts.map +1 -1
- package/dist/schema/VariantSchema.js +32 -18
- package/dist/schema/VariantSchema.js.map +1 -1
- package/dist/socket/Socket.d.ts +23 -1
- package/dist/socket/Socket.d.ts.map +1 -1
- package/dist/socket/Socket.js +36 -3
- package/dist/socket/Socket.js.map +1 -1
- package/dist/sql/Migrator.d.ts.map +1 -1
- package/dist/sql/Migrator.js +15 -3
- package/dist/sql/Migrator.js.map +1 -1
- package/dist/sql/SqlClient.d.ts +151 -12
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +156 -34
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/sql/SqlResolver.d.ts +9 -0
- package/dist/sql/SqlResolver.d.ts.map +1 -1
- package/dist/sql/SqlResolver.js +9 -0
- package/dist/sql/SqlResolver.js.map +1 -1
- package/dist/sql/Statement.d.ts +3 -1
- package/dist/sql/Statement.d.ts.map +1 -1
- package/dist/sql/Statement.js +24 -5
- package/dist/sql/Statement.js.map +1 -1
- package/dist/testing/TestClock.d.ts +16 -3
- package/dist/testing/TestClock.d.ts.map +1 -1
- package/dist/testing/TestClock.js +115 -23
- package/dist/testing/TestClock.js.map +1 -1
- package/dist/testing/TestSchema.d.ts +7 -1
- package/dist/testing/TestSchema.d.ts.map +1 -1
- package/dist/testing/TestSchema.js +9 -3
- package/dist/testing/TestSchema.js.map +1 -1
- package/dist/workflow/Activity.js +1 -0
- package/dist/workflow/Activity.js.map +1 -1
- package/dist/workflow/Workflow.d.ts +22 -0
- package/dist/workflow/Workflow.d.ts.map +1 -1
- package/dist/workflow/Workflow.js +15 -3
- package/dist/workflow/Workflow.js.map +1 -1
- package/dist/workflow/WorkflowEngine.d.ts +20 -1
- package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
- package/dist/workflow/WorkflowEngine.js +52 -24
- package/dist/workflow/WorkflowEngine.js.map +1 -1
- package/package.json +13 -3
- package/src/Array.ts +223 -61
- package/src/Bytes.ts +111 -0
- package/src/Channel.ts +287 -439
- package/src/ChannelSchema.ts +1 -49
- package/src/Chunk.ts +55 -61
- package/src/Config.ts +12 -86
- package/src/ConfigProvider.ts +41 -44
- package/src/Cron.ts +6 -3
- package/src/Duration.ts +70 -21
- package/src/Effect.ts +642 -220
- package/src/Equivalence.ts +7 -4
- package/src/Exit.ts +24 -9
- package/src/FiberHandle.ts +10 -9
- package/src/FiberMap.ts +13 -66
- package/src/FileSystem.ts +33 -9
- package/src/Graph.ts +171 -1263
- package/src/HashSet.ts +0 -60
- package/src/Iterable.ts +15 -14
- package/src/JsonSchema.ts +28 -3
- package/src/Layer.ts +2 -2
- package/src/ManagedRuntime.ts +72 -6
- package/src/Match.ts +65 -12
- package/src/Metric.ts +249 -507
- package/src/MutableHashMap.ts +4 -473
- package/src/Number.ts +2 -2
- package/src/Optic.ts +17 -332
- package/src/Path.ts +61 -8
- package/src/PubSub.ts +12 -7
- package/src/Queue.ts +5 -37
- package/src/Random.ts +1 -1
- package/src/RcMap.ts +14 -8
- package/src/Record.ts +51 -0
- package/src/Ref.ts +7 -104
- package/src/References.ts +5 -4
- package/src/RequestResolver.ts +46 -87
- package/src/Resource.ts +1 -1
- package/src/Runtime.ts +19 -18
- package/src/Schedule.ts +2 -94
- package/src/Schema.ts +596 -348
- package/src/SchemaAST.ts +20 -9
- package/src/SchemaGetter.ts +22 -5
- package/src/SchemaIssue.ts +44 -53
- package/src/SchemaRepresentation.ts +64 -1
- package/src/SchemaTransformation.ts +1 -1
- package/src/Scope.ts +12 -2
- package/src/ScopedCache.ts +17 -142
- package/src/SemVer.ts +1528 -0
- package/src/SemVerRange.ts +883 -0
- package/src/Sink.ts +6 -2
- package/src/Stream.ts +334 -1011
- package/src/String.ts +25 -12
- package/src/TextDiff.ts +766 -0
- package/src/TxHashMap.ts +1 -103
- package/src/TxHashSet.ts +48 -753
- package/src/TxRef.ts +4 -2
- package/src/ai/AiError.ts +69 -5
- package/src/ai/Chat.ts +10 -5
- package/src/ai/Decision.ts +119 -22
- package/src/ai/DecisionModel.ts +265 -109
- package/src/ai/EmbeddingModel.ts +25 -13
- package/src/ai/LanguageModel.ts +57 -51
- package/src/ai/McpClient.ts +1211 -0
- package/src/ai/McpClientError.ts +329 -0
- package/src/ai/McpProtocol.ts +2 -2
- package/src/ai/McpSchema.ts +153 -35
- package/src/ai/McpServer.ts +232 -275
- package/src/ai/Prompt.ts +49 -35
- package/src/ai/Response.ts +195 -65
- package/src/ai/Tool.ts +12 -4
- package/src/ai/Toolkit.ts +78 -10
- package/src/ai/index.ts +12 -0
- package/src/ai/internal/mcpCore.ts +13 -14
- package/src/ai/internal/mcpProtocol/v2024_11_05.ts +1 -1
- package/src/ai/internal/mcpProtocol/v2025_03_26.ts +1 -1
- package/src/ai/internal/mcpProtocol/v2025_06_18.ts +3 -3
- package/src/ai/internal/mcpProtocol/v2025_11_25.ts +3 -3
- package/src/ai/internal/mcpProtocol/v2026_07_28.ts +12 -14
- package/src/ai/internal/mcpProtocol.ts +22 -2
- package/src/ai/internal/mcpRuntime.ts +3 -4
- package/src/ai/internal/mcpSchema/v2024_11_05.ts +20 -13
- package/src/ai/internal/mcpSchema/v2025_03_26.ts +4 -2
- package/src/ai/internal/mcpSchema/v2025_06_18.ts +7 -7
- package/src/ai/internal/mcpSchema/v2025_11_25.ts +8 -8
- package/src/ai/internal/mcpSchema/v2026_07_28.ts +44 -42
- package/src/cli/CliError.ts +49 -4
- package/src/cli/Command.ts +316 -9
- package/src/cli/Completions.ts +10 -0
- package/src/cli/Flag.ts +218 -0
- package/src/cli/GlobalFlag.ts +3 -3
- package/src/cli/Param.ts +218 -0
- package/src/cli/TerminalCapabilities.ts +156 -0
- package/src/cli/index.ts +6 -0
- package/src/cli/internal/command.ts +10 -4
- package/src/cli/internal/completions/bash.ts +7 -5
- package/src/cli/internal/completions/descriptor.ts +20 -1
- package/src/cli/internal/completions/fish.ts +12 -10
- package/src/cli/internal/completions/powershell.ts +25 -13
- package/src/cli/internal/completions/zsh.ts +15 -8
- package/src/cli/internal/formatter.ts +18 -0
- package/src/cli/internal/lexer.ts +12 -5
- package/src/cli/internal/parser.ts +43 -14
- package/src/cli/internal/wizard.ts +2 -1
- package/src/cluster/ClusterCron.ts +94 -35
- package/src/cluster/ClusterMetrics.ts +149 -7
- package/src/cluster/ClusterWorkflowEngine.ts +164 -53
- package/src/cluster/Entity.ts +4 -0
- package/src/cluster/MessageStorage.ts +21 -3
- package/src/cluster/Runners.ts +145 -72
- package/src/cluster/Sharding.ts +118 -38
- package/src/cluster/ShardingConfig.ts +15 -0
- package/src/cluster/SqlMessageStorage.ts +58 -55
- package/src/cluster/SqlRunnerStorage.ts +10 -4
- package/src/cluster/internal/entityManager.ts +81 -11
- package/src/devtools/DevTools.ts +3 -2
- package/src/devtools/DevToolsClient.ts +27 -10
- package/src/encoding/Base64Url.ts +31 -0
- package/src/encoding/Ini.ts +3 -0
- package/src/encoding/JsonArray.ts +849 -0
- package/src/encoding/Ndjson.ts +211 -20
- package/src/encoding/SchemaBinary.ts +14 -48
- package/src/encoding/Sse.ts +1 -1
- package/src/encoding/Tar.ts +1417 -0
- package/src/encoding/Toml.ts +3 -3
- package/src/encoding/Xml.ts +2037 -0
- package/src/encoding/Yaml.ts +108 -36
- package/src/encoding/Zip.ts +1558 -0
- package/src/encoding/index.ts +24 -0
- package/src/eventlog/EventJournal.ts +611 -227
- package/src/eventlog/EventLog.ts +496 -196
- package/src/eventlog/EventLogEncryption.ts +128 -43
- package/src/eventlog/EventLogMessage.ts +62 -11
- package/src/eventlog/EventLogRemote.ts +77 -21
- package/src/eventlog/EventLogServer.ts +162 -20
- package/src/eventlog/EventLogServerEncrypted.ts +121 -80
- package/src/eventlog/EventLogServerUnencrypted.ts +180 -77
- package/src/eventlog/EventRow.ts +706 -0
- package/src/eventlog/SqlEventJournal.ts +453 -173
- package/src/eventlog/SqlEventLogServerEncrypted.ts +212 -83
- package/src/eventlog/SqlEventLogServerUnencrypted.ts +141 -62
- package/src/eventlog/index.ts +6 -0
- package/src/eventlog/internal/conflicts.ts +123 -0
- package/src/graphql/GraphQLClient.ts +17 -5
- package/src/graphql/GraphQLClientError.ts +5 -12
- package/src/graphql/GraphQLProtocol.ts +277 -20
- package/src/graphql/GraphQLResolver.ts +109 -230
- package/src/http/FetchHttpClient.ts +61 -8
- package/src/http/FindMyWay/internal/router.ts +13 -1
- package/src/http/Headers.ts +343 -163
- package/src/http/HttpClient.ts +144 -136
- package/src/http/HttpClientError.ts +10 -6
- package/src/http/HttpClientRequest.ts +315 -11
- package/src/http/HttpClientResponse.ts +71 -0
- package/src/http/HttpEffect.ts +25 -33
- package/src/http/HttpIncomingMessage.ts +3 -23
- package/src/http/HttpMiddleware.ts +265 -28
- package/src/http/HttpRouter.ts +67 -14
- package/src/http/HttpServerError.ts +14 -7
- package/src/http/HttpServerRequest.ts +73 -14
- package/src/http/HttpServerResponse.ts +49 -23
- package/src/http/HttpStaticServer.ts +29 -19
- package/src/http/HttpTraceContext.ts +1 -1
- package/src/http/MultipartParser/internal/contentType.ts +107 -6
- package/src/http/MultipartParser/internal/headers.ts +4 -16
- package/src/http/MultipartParser/internal/multipart.ts +10 -32
- package/src/http/Url.ts +8 -2
- package/src/http/UrlParams.ts +225 -26
- package/src/http/internal/compression.ts +3 -17
- package/src/http/internal/compressionBody.ts +56 -0
- package/src/http/internal/decompression.ts +235 -0
- package/src/http/internal/lazyStream.ts +25 -0
- package/src/http/internal/requestState.ts +33 -0
- package/src/http/internal/tracing.ts +21 -4
- package/src/http/internal/urlParams.ts +5 -0
- package/src/http/internal/webResponse.ts +20 -0
- package/src/http-api/HttpApi.ts +1 -1
- package/src/http-api/HttpApiBuilder.ts +151 -23
- package/src/http-api/HttpApiClient.ts +160 -31
- package/src/http-api/HttpApiEndpoint.ts +144 -33
- package/src/http-api/HttpApiError.ts +55 -0
- package/src/http-api/HttpApiScalar.ts +4 -3
- package/src/http-api/HttpApiSchema.ts +275 -13
- package/src/http-api/HttpApiSwagger.ts +11 -4
- package/src/http-api/HttpApiTest.ts +33 -9
- package/src/http-api/OpenApi.ts +84 -42
- package/src/http-api/internal/path.ts +40 -12
- package/src/index.ts +24 -0
- package/src/internal/core.ts +22 -2
- package/src/internal/dateTime.ts +20 -7
- package/src/internal/effect.ts +125 -88
- package/src/internal/graphql.ts +30 -7
- package/src/internal/hashMap.ts +2 -2
- package/src/internal/hydration.ts +15 -0
- package/src/internal/inflate.ts +710 -0
- package/src/internal/record.ts +6 -0
- package/src/internal/request.ts +21 -6
- package/src/internal/schedule.ts +20 -39
- package/src/internal/schema/fromJsonSchemaDocument.ts +262 -193
- package/src/internal/schema/interpreter.ts +58 -45
- package/src/internal/schema/standardSchema.ts +32 -30
- package/src/internal/schema/toCodeDocument.ts +8 -3
- package/src/internal/schema/toCodec.ts +116 -1
- package/src/internal/schema/toFormatter.ts +6 -6
- package/src/internal/schema/toJsonSchemaDocument.ts +69 -39
- package/src/internal/trie.ts +1 -3
- package/src/internal/uuid.ts +15 -10
- package/src/internal/version.ts +1 -1
- package/src/net/NetAddress.ts +2 -9
- package/src/observability/Otlp.ts +18 -0
- package/src/observability/OtlpExporter.ts +19 -15
- package/src/observability/OtlpLogger.ts +31 -2
- package/src/observability/OtlpMetrics.ts +35 -4
- package/src/observability/OtlpResource.ts +16 -6
- package/src/observability/OtlpSerialization.ts +17 -3
- package/src/observability/OtlpTracer.ts +32 -3
- package/src/observability/internal/protobuf.ts +2 -10
- package/src/persistence/PersistedCache.ts +3 -1
- package/src/persistence/PersistedQueue.ts +223 -153
- package/src/persistence/Persistence.ts +64 -30
- package/src/persistence/RateLimiter.ts +18 -21
- package/src/persistence/UserDirectories.ts +273 -0
- package/src/persistence/index.ts +6 -0
- package/src/process/ChildProcess.ts +2 -1
- package/src/reactivity/AsyncResult.ts +35 -38
- package/src/reactivity/Atom.ts +134 -166
- package/src/reactivity/AtomHttpApi.ts +10 -16
- package/src/reactivity/AtomRegistry.ts +53 -30
- package/src/reactivity/AtomRpc.ts +6 -22
- package/src/reactivity/Hydration.ts +53 -12
- package/src/reactivity/Reactivity.ts +97 -39
- package/src/rpc/Rpc.ts +21 -0
- package/src/rpc/RpcClient.ts +285 -104
- package/src/rpc/RpcSerialization.ts +21 -5
- package/src/rpc/RpcServer.ts +11 -20
- package/src/schema/VariantSchema.ts +86 -22
- package/src/socket/Socket.ts +45 -20
- package/src/sql/Migrator.ts +19 -9
- package/src/sql/SqlClient.ts +275 -36
- package/src/sql/SqlResolver.ts +9 -0
- package/src/sql/Statement.ts +35 -8
- package/src/testing/TestClock.ts +147 -29
- package/src/testing/TestSchema.ts +9 -3
- package/src/workflow/Activity.ts +1 -0
- package/src/workflow/Workflow.ts +31 -5
- package/src/workflow/WorkflowEngine.ts +93 -31
- package/dist/http/internal/preResponseHandler.d.ts +0 -2
- package/dist/http/internal/preResponseHandler.d.ts.map +0 -1
- package/dist/http/internal/preResponseHandler.js +0 -14
- package/dist/http/internal/preResponseHandler.js.map +0 -1
- package/src/http/internal/preResponseHandler.ts +0 -19
|
@@ -0,0 +1,1211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connects to MCP servers with scoped Effect clients.
|
|
3
|
+
*
|
|
4
|
+
* Clients discover tools, prompts and resources using the protocol revision selected by
|
|
5
|
+
* their transport. `callTool` returns tool-reported errors as results; supplying a schema
|
|
6
|
+
* turns them into a `ToolError` reason that retains the original result. Transport and
|
|
7
|
+
* protocol failures fail the Effect. Interactive server requests, subscriptions, OAuth
|
|
8
|
+
* and retries are not included.
|
|
9
|
+
*
|
|
10
|
+
* @stability experimental
|
|
11
|
+
* @since 4.0.6
|
|
12
|
+
*/
|
|
13
|
+
import * as ByteSize from "../ByteSize.ts"
|
|
14
|
+
import type * as Cause from "../Cause.ts"
|
|
15
|
+
import * as Context from "../Context.ts"
|
|
16
|
+
import * as Deferred from "../Deferred.ts"
|
|
17
|
+
import * as Duration from "../Duration.ts"
|
|
18
|
+
import * as Effect from "../Effect.ts"
|
|
19
|
+
import * as Base64 from "../encoding/Base64.ts"
|
|
20
|
+
import * as Sse from "../encoding/Sse.ts"
|
|
21
|
+
import * as HttpClient from "../http/HttpClient.ts"
|
|
22
|
+
import * as HttpClientRequest from "../http/HttpClientRequest.ts"
|
|
23
|
+
import type * as HttpClientResponse from "../http/HttpClientResponse.ts"
|
|
24
|
+
import * as Layer from "../Layer.ts"
|
|
25
|
+
import * as Option from "../Option.ts"
|
|
26
|
+
import * as Predicate from "../Predicate.ts"
|
|
27
|
+
import type * as ChildProcess from "../process/ChildProcess.ts"
|
|
28
|
+
import { ChildProcessSpawner } from "../process/ChildProcessSpawner.ts"
|
|
29
|
+
import * as Queue from "../Queue.ts"
|
|
30
|
+
import type * as Rpc from "../rpc/Rpc.ts"
|
|
31
|
+
import * as Schema from "../Schema.ts"
|
|
32
|
+
import type * as Scope from "../Scope.ts"
|
|
33
|
+
import * as Stream from "../Stream.ts"
|
|
34
|
+
import { BASE64_SENTINEL_PREFIX, BASE64_SENTINEL_SUFFIX } from "./internal/mcpProtocol.ts"
|
|
35
|
+
import {
|
|
36
|
+
ClosedError,
|
|
37
|
+
ConfigurationError,
|
|
38
|
+
HttpError,
|
|
39
|
+
isMcpClientError,
|
|
40
|
+
LimitError,
|
|
41
|
+
McpClientError,
|
|
42
|
+
type McpClientErrorReason,
|
|
43
|
+
ProtocolError,
|
|
44
|
+
TimeoutError,
|
|
45
|
+
ToolError,
|
|
46
|
+
TransportError,
|
|
47
|
+
UnsupportedError,
|
|
48
|
+
ValidationError
|
|
49
|
+
} from "./McpClientError.ts"
|
|
50
|
+
import type * as McpProtocol from "./McpProtocol.ts"
|
|
51
|
+
import * as McpSchema from "./McpSchema.ts"
|
|
52
|
+
import * as Tool from "./Tool.ts"
|
|
53
|
+
import * as Toolkit from "./Toolkit.ts"
|
|
54
|
+
|
|
55
|
+
// =============================================================================
|
|
56
|
+
// Models
|
|
57
|
+
// =============================================================================
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Supported MCP wire protocol revisions.
|
|
61
|
+
*
|
|
62
|
+
* @stability experimental
|
|
63
|
+
* @category models
|
|
64
|
+
* @since 4.0.6
|
|
65
|
+
*/
|
|
66
|
+
export type ProtocolVersion = "2025-11-25" | "2026-07-28"
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Service tag for applications that provide one default MCP connection.
|
|
70
|
+
*
|
|
71
|
+
* @stability experimental
|
|
72
|
+
* @category services
|
|
73
|
+
* @since 4.0.6
|
|
74
|
+
*/
|
|
75
|
+
export const McpClient: Context.Service<McpClient, McpClient> = Context.Service<McpClient>("effect/ai/McpClient")
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A scoped connection to one MCP server.
|
|
79
|
+
*
|
|
80
|
+
* @stability experimental
|
|
81
|
+
* @category models
|
|
82
|
+
* @since 4.0.6
|
|
83
|
+
*/
|
|
84
|
+
export interface McpClient {
|
|
85
|
+
readonly [TypeId]: typeof TypeId
|
|
86
|
+
readonly protocolVersion: ProtocolVersion
|
|
87
|
+
readonly serverInfo: McpSchema.Implementation | undefined
|
|
88
|
+
readonly instructions?: string | undefined
|
|
89
|
+
/**
|
|
90
|
+
* Returns every tool page as one snapshot, bounded by the deadline, 100 pages and 10,000 tools.
|
|
91
|
+
* `timeout` overrides the client's discovery deadline.
|
|
92
|
+
*/
|
|
93
|
+
readonly listTools: (
|
|
94
|
+
options?: { readonly timeout?: Duration.Input | undefined }
|
|
95
|
+
) => Effect.Effect<ReadonlyArray<McpSchema.Tool>, McpClientError>
|
|
96
|
+
/** Returns every prompt page as one snapshot with the same bounds as `listTools`. */
|
|
97
|
+
readonly listPrompts: (
|
|
98
|
+
options?: { readonly timeout?: Duration.Input | undefined }
|
|
99
|
+
) => Effect.Effect<ReadonlyArray<McpSchema.Prompt>, McpClientError>
|
|
100
|
+
/** Gets the messages for a discovered prompt. Unbounded unless `timeout` is supplied. */
|
|
101
|
+
readonly getPrompt: (
|
|
102
|
+
params: {
|
|
103
|
+
readonly prompt: McpSchema.Prompt
|
|
104
|
+
readonly arguments?: typeof McpSchema.GetPrompt.payloadSchema.Type["arguments"]
|
|
105
|
+
},
|
|
106
|
+
options?: { readonly timeout?: Duration.Input | undefined }
|
|
107
|
+
) => Effect.Effect<McpSchema.GetPromptResult, McpClientError>
|
|
108
|
+
/** Returns every resource page as one snapshot with the same bounds as `listTools`. */
|
|
109
|
+
readonly listResources: (
|
|
110
|
+
options?: { readonly timeout?: Duration.Input | undefined }
|
|
111
|
+
) => Effect.Effect<ReadonlyArray<McpSchema.Resource>, McpClientError>
|
|
112
|
+
/** Reads the complete contents of a resource URI. Unbounded unless `timeout` is supplied. */
|
|
113
|
+
readonly readResource: (
|
|
114
|
+
params: { readonly uri: string },
|
|
115
|
+
options?: { readonly timeout?: Duration.Input | undefined }
|
|
116
|
+
) => Effect.Effect<McpSchema.ReadResourceResult, McpClientError>
|
|
117
|
+
/**
|
|
118
|
+
* Calls a discovered tool, optionally decoding with a schema. Errors retain the full result.
|
|
119
|
+
* Unbounded unless `timeout` is supplied.
|
|
120
|
+
*/
|
|
121
|
+
readonly callTool: {
|
|
122
|
+
(
|
|
123
|
+
params: {
|
|
124
|
+
readonly tool: McpSchema.Tool
|
|
125
|
+
readonly schema?: undefined
|
|
126
|
+
readonly arguments?: typeof McpSchema.CallTool.payloadSchema.Type["arguments"]
|
|
127
|
+
},
|
|
128
|
+
options?: { readonly timeout?: Duration.Input | undefined }
|
|
129
|
+
): Effect.Effect<McpSchema.CallToolResult, McpClientError>
|
|
130
|
+
<S extends Schema.Top>(
|
|
131
|
+
params: {
|
|
132
|
+
readonly tool: McpSchema.Tool
|
|
133
|
+
readonly schema: S
|
|
134
|
+
readonly arguments?: typeof McpSchema.CallTool.payloadSchema.Type["arguments"]
|
|
135
|
+
},
|
|
136
|
+
options?: { readonly timeout?: Duration.Input | undefined }
|
|
137
|
+
): Effect.Effect<S["Type"], McpClientError, S["DecodingServices"]>
|
|
138
|
+
<S extends Schema.Top = never>(
|
|
139
|
+
params: {
|
|
140
|
+
readonly tool: McpSchema.Tool
|
|
141
|
+
readonly schema?: S | undefined
|
|
142
|
+
readonly arguments?: typeof McpSchema.CallTool.payloadSchema.Type["arguments"]
|
|
143
|
+
},
|
|
144
|
+
options?: { readonly timeout?: Duration.Input | undefined }
|
|
145
|
+
): Effect.Effect<McpSchema.CallToolResult | S["Type"], McpClientError, S["DecodingServices"]>
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Returns whether a value is an MCP client.
|
|
151
|
+
*
|
|
152
|
+
* @stability experimental
|
|
153
|
+
* @category guards
|
|
154
|
+
* @since 4.0.6
|
|
155
|
+
*/
|
|
156
|
+
export const isMcpClient = (value: unknown): value is McpClient => Predicate.hasProperty(value, TypeId)
|
|
157
|
+
|
|
158
|
+
// =============================================================================
|
|
159
|
+
// Constructors
|
|
160
|
+
// =============================================================================
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Constructs and connects a client using the supplied MCP transport service and its protocol adapter.
|
|
164
|
+
*
|
|
165
|
+
* **Details**
|
|
166
|
+
*
|
|
167
|
+
* `name`, `version` and the optional `title`, `description`, `websiteUrl` and
|
|
168
|
+
* `icons` identify the client to the server. `timeout` defaults to 60 seconds
|
|
169
|
+
* and bounds initialization and each complete `listTools`, `listPrompts` or
|
|
170
|
+
* `listResources` scan. `callTool`, `getPrompt` and `readResource` have no
|
|
171
|
+
* deadline unless their own `timeout` option is supplied.
|
|
172
|
+
* Schema decoding requires the schema's services from the caller.
|
|
173
|
+
*
|
|
174
|
+
* @stability experimental
|
|
175
|
+
* @category constructors
|
|
176
|
+
* @since 4.0.6
|
|
177
|
+
*/
|
|
178
|
+
export const make: (options: {
|
|
179
|
+
readonly name: string
|
|
180
|
+
readonly version: string
|
|
181
|
+
readonly title?: string | undefined
|
|
182
|
+
readonly description?: string | undefined
|
|
183
|
+
readonly websiteUrl?: string | undefined
|
|
184
|
+
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
185
|
+
readonly timeout?: Duration.Input | undefined
|
|
186
|
+
}) => Effect.Effect<
|
|
187
|
+
McpClient,
|
|
188
|
+
McpClientError,
|
|
189
|
+
Scope.Scope | Transport
|
|
190
|
+
> = Effect.fnUntraced(function*(options: Options): Effect.fn.Return<
|
|
191
|
+
McpClient,
|
|
192
|
+
McpClientError,
|
|
193
|
+
Scope.Scope | Transport
|
|
194
|
+
> {
|
|
195
|
+
const transport = yield* Transport
|
|
196
|
+
const protocol = transport.protocol
|
|
197
|
+
const version = protocol.protocolVersion
|
|
198
|
+
const modern = version === "2026-07-28"
|
|
199
|
+
const timeout = options.timeout ?? DEFAULT_TIMEOUT
|
|
200
|
+
const closed = yield* Deferred.make<never, McpClientError>()
|
|
201
|
+
yield* Effect.addFinalizer(() =>
|
|
202
|
+
Deferred.fail(closed, fail(new ClosedError({ description: "MCP client scope closed" })))
|
|
203
|
+
)
|
|
204
|
+
let nextId = 1
|
|
205
|
+
|
|
206
|
+
const clientInfo = encodeImplementation({
|
|
207
|
+
name: options.name,
|
|
208
|
+
title: options.title,
|
|
209
|
+
version: options.version,
|
|
210
|
+
description: options.description,
|
|
211
|
+
websiteUrl: options.websiteUrl,
|
|
212
|
+
icons: options.icons
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
// Modern requests carry the client identity in every request.
|
|
216
|
+
// https://modelcontextprotocol.io/specification/2026-07-28/basic/index
|
|
217
|
+
const meta = {
|
|
218
|
+
"io.modelcontextprotocol/protocolVersion": version,
|
|
219
|
+
"io.modelcontextprotocol/clientInfo": clientInfo,
|
|
220
|
+
"io.modelcontextprotocol/clientCapabilities": {}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const request = Effect.fnUntraced(function*<A>(
|
|
224
|
+
method: string,
|
|
225
|
+
params: Record<string, unknown>,
|
|
226
|
+
tool?: McpSchema.Tool
|
|
227
|
+
): Effect.fn.Return<A, McpClientError> {
|
|
228
|
+
const rpc = protocol.clientRpcs.requests.get(method) as Rpc.AnyWithProps | undefined
|
|
229
|
+
if (rpc === undefined) {
|
|
230
|
+
return yield* fail(new UnsupportedError({ description: `Unsupported MCP method: ${method}` }))
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const codecs = protocol.payloadCodecs(rpc)
|
|
234
|
+
const payload = yield* codecs.decode(modern ? { ...params, _meta: meta } : params).pipe(
|
|
235
|
+
Effect.flatMap(codecs.encode),
|
|
236
|
+
Effect.mapError(validationError)
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
const response = yield* transport.request(
|
|
240
|
+
{ jsonrpc: "2.0", id: nextId++, method, params: payload as Readonly<Record<string, unknown>> },
|
|
241
|
+
tool
|
|
242
|
+
)
|
|
243
|
+
if ("error" in response) {
|
|
244
|
+
return yield* fail(
|
|
245
|
+
new ProtocolError({
|
|
246
|
+
code: response.error.code,
|
|
247
|
+
data: response.error.data,
|
|
248
|
+
description: response.error.message
|
|
249
|
+
})
|
|
250
|
+
)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
let result: unknown = response.result
|
|
254
|
+
// Older modern peers may omit the complete discriminator.
|
|
255
|
+
if (modern && isRecord(result) && result.resultType === undefined) result = { ...result, resultType: "complete" }
|
|
256
|
+
if (method === "tools/list" && isRecord(result) && Array.isArray(result.tools)) {
|
|
257
|
+
result = { ...result, tools: result.tools.filter((tool) => !requiresTasks(tool)) }
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const validated = yield* decodeUnknown(rpc.successSchema, result)
|
|
261
|
+
if (isRecord(result) && result.resultType === "input_required") {
|
|
262
|
+
return yield* fail(new UnsupportedError({ description: "MCP input continuation is not supported" }))
|
|
263
|
+
}
|
|
264
|
+
const publicRpc = publicRpcs.get(method)
|
|
265
|
+
return (publicRpc === undefined ? validated : yield* decodeUnknown(publicRpc.successSchema, result)) as A
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
// Initialization and discovery default to `timeout`; other operations are bounded only on request.
|
|
269
|
+
const withDeadline = <A, E, R>(
|
|
270
|
+
effect: Effect.Effect<A, E, R>,
|
|
271
|
+
operation: string,
|
|
272
|
+
duration: Duration.Input | undefined
|
|
273
|
+
) => {
|
|
274
|
+
const open = Effect.raceFirst(effect, Deferred.await(closed))
|
|
275
|
+
return duration === undefined ? open : open.pipe(
|
|
276
|
+
Effect.timeoutOrElse({
|
|
277
|
+
duration,
|
|
278
|
+
orElse: () => Effect.fail(fail(new TimeoutError({ operation })))
|
|
279
|
+
})
|
|
280
|
+
)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const initialize = Effect.gen(function*() {
|
|
284
|
+
if (!modern) {
|
|
285
|
+
return yield* request<InitializeResult>("initialize", {
|
|
286
|
+
protocolVersion: version,
|
|
287
|
+
capabilities: {},
|
|
288
|
+
clientInfo
|
|
289
|
+
})
|
|
290
|
+
}
|
|
291
|
+
const discover = request<InitializeResult>("server/discover", {})
|
|
292
|
+
// Retry once when the server rejects a version that it reports as supported.
|
|
293
|
+
return yield* discover.pipe(Effect.catchIf((error) => {
|
|
294
|
+
const reason = error.reason
|
|
295
|
+
if (reason._tag !== "ProtocolError" && reason._tag !== "HttpError") return false
|
|
296
|
+
const rejection = Option.getOrUndefined(decodeVersionRejection(reason.data))
|
|
297
|
+
return reason.code === McpSchema.UNSUPPORTED_PROTOCOL_VERSION_ERROR_CODE && rejection?.requested === version &&
|
|
298
|
+
rejection.supported.includes(version)
|
|
299
|
+
}, () => discover))
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
const { capabilities, instructions, serverInfo } = yield* withDeadline(
|
|
303
|
+
Effect.gen(function*() {
|
|
304
|
+
const result = yield* initialize
|
|
305
|
+
if (modern ? !result.supportedVersions?.includes(version) : result.protocolVersion !== version) {
|
|
306
|
+
return yield* fail(
|
|
307
|
+
new UnsupportedError({ description: "Server does not support the explicitly selected protocol version" })
|
|
308
|
+
)
|
|
309
|
+
}
|
|
310
|
+
const identity = modern ? result._meta?.["io.modelcontextprotocol/serverInfo"] : result.serverInfo
|
|
311
|
+
const capabilities = yield* decodeServerCapabilities(result.capabilities)
|
|
312
|
+
const serverInfo = identity === undefined ? undefined : yield* decodeImplementation(identity)
|
|
313
|
+
if (!modern) yield* transport.notify({ jsonrpc: "2.0", method: "notifications/initialized" })
|
|
314
|
+
return { capabilities, instructions: result.instructions, serverInfo }
|
|
315
|
+
}).pipe(
|
|
316
|
+
Effect.mapError((cause) =>
|
|
317
|
+
Schema.isSchemaError(cause)
|
|
318
|
+
? fail(new ProtocolError({ description: "Invalid MCP initialization result", cause }))
|
|
319
|
+
: cause
|
|
320
|
+
)
|
|
321
|
+
),
|
|
322
|
+
"initialization",
|
|
323
|
+
timeout
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
// Retrieval requires the capability; discovery treats a missing one as empty.
|
|
327
|
+
const call = <A>(
|
|
328
|
+
kind: Capability,
|
|
329
|
+
method: string,
|
|
330
|
+
params: Record<string, unknown>,
|
|
331
|
+
tool?: McpSchema.Tool
|
|
332
|
+
): Effect.Effect<A, McpClientError> =>
|
|
333
|
+
capabilities[kind] === undefined
|
|
334
|
+
? Effect.fail(fail(new UnsupportedError({ description: `Server does not advertise ${kind}` })))
|
|
335
|
+
: request<A>(method, params, tool)
|
|
336
|
+
|
|
337
|
+
const list = <K extends Capability, A>(kind: K) =>
|
|
338
|
+
Effect.fnUntraced(
|
|
339
|
+
function*(_options?: CallOptions) {
|
|
340
|
+
if (capabilities[kind] === undefined) return []
|
|
341
|
+
const items: Array<A> = []
|
|
342
|
+
const cursors = new Set<string>()
|
|
343
|
+
let cursor: string | undefined
|
|
344
|
+
for (let page = 0; page < MAX_DISCOVERY_PAGES; page++) {
|
|
345
|
+
const result = yield* request<ListResult<K, A>>(`${kind}/list`, cursor === undefined ? {} : { cursor })
|
|
346
|
+
if (items.length + result[kind].length > MAX_DISCOVERY_ITEMS) {
|
|
347
|
+
return yield* limitError(`MCP ${kind} discovery exceeded its item limit`)
|
|
348
|
+
}
|
|
349
|
+
items.push(...result[kind])
|
|
350
|
+
if (result.nextCursor === undefined) return items
|
|
351
|
+
if (cursors.has(result.nextCursor)) {
|
|
352
|
+
return yield* limitError(`MCP ${kind} discovery repeated a cursor`)
|
|
353
|
+
}
|
|
354
|
+
cursors.add(cursor = result.nextCursor)
|
|
355
|
+
}
|
|
356
|
+
return yield* limitError(`MCP ${kind} discovery exceeded its page limit`)
|
|
357
|
+
},
|
|
358
|
+
(effect, callOptions) => withDeadline(effect, `${kind} discovery`, callOptions?.timeout ?? timeout)
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
const listTools = list<"tools", McpSchema.Tool>("tools")
|
|
362
|
+
|
|
363
|
+
const callTool = Effect.fnUntraced(
|
|
364
|
+
function*<S extends Schema.Top>(
|
|
365
|
+
params: {
|
|
366
|
+
readonly tool: McpSchema.Tool
|
|
367
|
+
readonly schema?: S | undefined
|
|
368
|
+
readonly arguments?: typeof McpSchema.CallTool.payloadSchema.Type["arguments"]
|
|
369
|
+
},
|
|
370
|
+
_options?: CallOptions
|
|
371
|
+
) {
|
|
372
|
+
const result = yield* call<McpSchema.CallToolResult>(
|
|
373
|
+
"tools",
|
|
374
|
+
"tools/call",
|
|
375
|
+
{ name: params.tool.name, ...(params.arguments === undefined ? {} : { arguments: params.arguments }) },
|
|
376
|
+
params.tool
|
|
377
|
+
)
|
|
378
|
+
if (params.schema === undefined) return result
|
|
379
|
+
if (result.isError === true) {
|
|
380
|
+
return yield* fail(new ToolError({ result }))
|
|
381
|
+
}
|
|
382
|
+
return yield* Schema.decodeUnknownEffect(params.schema)(result.structuredContent).pipe(
|
|
383
|
+
Effect.mapError((cause) =>
|
|
384
|
+
fail(new ValidationError({ description: "MCP structured result validation failed", cause }))
|
|
385
|
+
)
|
|
386
|
+
)
|
|
387
|
+
},
|
|
388
|
+
(effect, _params, callOptions) => withDeadline(effect, "tools/call", callOptions?.timeout)
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
return {
|
|
392
|
+
[TypeId]: TypeId,
|
|
393
|
+
protocolVersion: version,
|
|
394
|
+
serverInfo,
|
|
395
|
+
instructions,
|
|
396
|
+
listTools: (callOptions) =>
|
|
397
|
+
listTools(callOptions).pipe(Effect.map((tools) => tools.filter((tool) => transport.isCallable(tool)))),
|
|
398
|
+
listPrompts: list("prompts"),
|
|
399
|
+
listResources: list("resources"),
|
|
400
|
+
getPrompt: (params, callOptions) =>
|
|
401
|
+
withDeadline(
|
|
402
|
+
call<McpSchema.GetPromptResult>("prompts", "prompts/get", {
|
|
403
|
+
name: params.prompt.name,
|
|
404
|
+
...(params.arguments === undefined ? {} : { arguments: params.arguments })
|
|
405
|
+
}),
|
|
406
|
+
"prompts/get",
|
|
407
|
+
callOptions?.timeout
|
|
408
|
+
),
|
|
409
|
+
readResource: (params, callOptions) =>
|
|
410
|
+
withDeadline(
|
|
411
|
+
call<McpSchema.ReadResourceResult>("resources", "resources/read", { uri: params.uri }),
|
|
412
|
+
"resources/read",
|
|
413
|
+
callOptions?.timeout
|
|
414
|
+
),
|
|
415
|
+
callTool: callTool as McpClient["callTool"]
|
|
416
|
+
}
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
// =============================================================================
|
|
420
|
+
// Toolkit
|
|
421
|
+
// =============================================================================
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Discovers remote tools and binds their handlers using the standard Toolkit implementation.
|
|
425
|
+
*
|
|
426
|
+
* **Details**
|
|
427
|
+
*
|
|
428
|
+
* Pass an optional prefix such as `"reports__"` to qualify model tool names.
|
|
429
|
+
* Remote JSON Schemas are advertised without local schema import. Results become
|
|
430
|
+
* text; tool-reported and operational failures fail the Effect. Use `Tool.make`
|
|
431
|
+
* or `Tool.dynamic` with `Toolkit.make` for custom validation, approval or results.
|
|
432
|
+
* Build a new toolkit to discover changes between model turns.
|
|
433
|
+
*
|
|
434
|
+
* @stability experimental
|
|
435
|
+
* @category constructors
|
|
436
|
+
* @since 4.0.6
|
|
437
|
+
*/
|
|
438
|
+
export const toolkit: (client: McpClient, prefix?: string) => Effect.Effect<
|
|
439
|
+
Toolkit.WithHandler<
|
|
440
|
+
Record<
|
|
441
|
+
string,
|
|
442
|
+
Tool.Tool<string, {
|
|
443
|
+
readonly parameters: typeof Schema.Unknown
|
|
444
|
+
readonly success: typeof Schema.String
|
|
445
|
+
readonly failure: typeof McpClientError
|
|
446
|
+
readonly failureMode: "error"
|
|
447
|
+
}>
|
|
448
|
+
>
|
|
449
|
+
>,
|
|
450
|
+
McpClientError
|
|
451
|
+
> = Effect.fnUntraced(function*(client: McpClient, prefix = "") {
|
|
452
|
+
const descriptors = yield* client.listTools()
|
|
453
|
+
const tools: Array<
|
|
454
|
+
Tool.Tool<string, {
|
|
455
|
+
readonly parameters: typeof Schema.Unknown
|
|
456
|
+
readonly success: typeof Schema.String
|
|
457
|
+
readonly failure: typeof McpClientError
|
|
458
|
+
readonly failureMode: "error"
|
|
459
|
+
}>
|
|
460
|
+
> = []
|
|
461
|
+
const handlers: Record<string, (params: unknown) => Effect.Effect<string, McpClientError>> = Object.create(null)
|
|
462
|
+
|
|
463
|
+
for (const descriptor of descriptors) {
|
|
464
|
+
const name = `${prefix}${descriptor.name}`
|
|
465
|
+
if (!/^[a-zA-Z0-9_-]{1,64}$/.test(name) || Object.hasOwn(handlers, name)) {
|
|
466
|
+
return yield* fail(new ConfigurationError({ description: `Invalid or duplicate MCP model tool name: ${name}` }))
|
|
467
|
+
}
|
|
468
|
+
tools.push(
|
|
469
|
+
Tool.dynamic(name, {
|
|
470
|
+
parameters: descriptor.inputSchema,
|
|
471
|
+
description: descriptor.description,
|
|
472
|
+
success: Schema.String,
|
|
473
|
+
failure: McpClientError
|
|
474
|
+
}).annotate(Tool.Strict, false)
|
|
475
|
+
)
|
|
476
|
+
handlers[name] = Effect.fnUntraced(function*(params: unknown) {
|
|
477
|
+
const args = yield* decodeToolArguments(params).pipe(
|
|
478
|
+
Effect.mapError((cause) =>
|
|
479
|
+
fail(new ValidationError({ description: "MCP tool arguments must be a JSON object", cause }))
|
|
480
|
+
)
|
|
481
|
+
)
|
|
482
|
+
const result = yield* client.callTool({ tool: descriptor, arguments: args })
|
|
483
|
+
if (result.isError === true) {
|
|
484
|
+
return yield* fail(new ToolError({ result }))
|
|
485
|
+
}
|
|
486
|
+
return yield* toText(result)
|
|
487
|
+
})
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const toolkit = Toolkit.make(...tools)
|
|
491
|
+
return yield* toolkit.pipe(Effect.provideContext(yield* toolkit.toHandlers(handlers)))
|
|
492
|
+
})
|
|
493
|
+
|
|
494
|
+
// =============================================================================
|
|
495
|
+
// Transports
|
|
496
|
+
// =============================================================================
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Service supplied by the built-in MCP transport constructors and layers.
|
|
500
|
+
*
|
|
501
|
+
* **Details**
|
|
502
|
+
*
|
|
503
|
+
* Transport construction owns cleanup through its Effect scope.
|
|
504
|
+
*
|
|
505
|
+
* @stability experimental
|
|
506
|
+
* @category services
|
|
507
|
+
* @since 4.0.6
|
|
508
|
+
*/
|
|
509
|
+
export const Transport: Context.Service<Transport, Transport> = Context.Service<Transport>(
|
|
510
|
+
"effect/ai/McpClient/Transport"
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Exchanges JSON-RPC messages with one MCP server using its protocol adapter.
|
|
515
|
+
*
|
|
516
|
+
* @stability experimental
|
|
517
|
+
* @category models
|
|
518
|
+
* @since 4.0.6
|
|
519
|
+
*/
|
|
520
|
+
export interface Transport {
|
|
521
|
+
readonly [TransportTypeId]: typeof TransportTypeId
|
|
522
|
+
readonly protocol: McpProtocol.ProtocolAdapter<ProtocolVersion>
|
|
523
|
+
/** Sends a request and waits for its response. `tool` supplies header routing for tool calls. */
|
|
524
|
+
readonly request: (
|
|
525
|
+
message: McpSchema.JsonRpcRequest,
|
|
526
|
+
tool?: McpSchema.Tool
|
|
527
|
+
) => Effect.Effect<McpSchema.JsonRpcResponse, McpClientError>
|
|
528
|
+
/** Sends a notification without waiting for a reply. */
|
|
529
|
+
readonly notify: (message: McpSchema.JsonRpcNotification) => Effect.Effect<void, McpClientError>
|
|
530
|
+
/** Returns whether the transport can route a call to the tool. */
|
|
531
|
+
readonly isCallable: (tool: McpSchema.Tool) => boolean
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Starts a scoped subprocess using newline-delimited JSON-RPC.
|
|
536
|
+
*
|
|
537
|
+
* @stability experimental
|
|
538
|
+
* @category constructors
|
|
539
|
+
* @since 4.0.6
|
|
540
|
+
*/
|
|
541
|
+
export const stdio: (options: {
|
|
542
|
+
readonly command: ChildProcess.Command
|
|
543
|
+
readonly protocol: McpProtocol.ProtocolAdapter<ProtocolVersion>
|
|
544
|
+
readonly maxMessageBytes?: ByteSize.Input | undefined
|
|
545
|
+
}) => Effect.Effect<Transport, McpClientError, ChildProcessSpawner | Scope.Scope> = Effect.fnUntraced(
|
|
546
|
+
function*(options: {
|
|
547
|
+
readonly command: ChildProcess.Command
|
|
548
|
+
readonly protocol: Protocol
|
|
549
|
+
readonly maxMessageBytes?: ByteSize.Input | undefined
|
|
550
|
+
}): Effect.fn.Return<Transport, McpClientError, ChildProcessSpawner | Scope.Scope> {
|
|
551
|
+
const maxBytes = yield* messageLimit(options.maxMessageBytes)
|
|
552
|
+
const spawner = yield* ChildProcessSpawner
|
|
553
|
+
const process = yield* spawner.spawn(options.command).pipe(
|
|
554
|
+
Effect.mapError((cause) => fail(new TransportError({ description: "Cannot spawn MCP server", cause })))
|
|
555
|
+
)
|
|
556
|
+
|
|
557
|
+
const pending = new Map<McpSchema.RequestId, Deferred.Deferred<McpSchema.JsonRpcResponse>>()
|
|
558
|
+
const failure = yield* Deferred.make<never, McpClientError>()
|
|
559
|
+
let failed: McpClientError | undefined
|
|
560
|
+
|
|
561
|
+
const close = (error: McpClientError) =>
|
|
562
|
+
Effect.suspend(() => {
|
|
563
|
+
failed ??= error
|
|
564
|
+
return Deferred.fail(failure, failed)
|
|
565
|
+
})
|
|
566
|
+
|
|
567
|
+
const input = yield* Queue.unbounded<string, Cause.Done>()
|
|
568
|
+
|
|
569
|
+
const write = Effect.fnUntraced(function*(message: McpSchema.JsonRpcMessage) {
|
|
570
|
+
if (failed !== undefined) return yield* failed
|
|
571
|
+
const json = yield* encodeMessage(message, maxBytes)
|
|
572
|
+
yield* Queue.offer(input, json + "\n")
|
|
573
|
+
})
|
|
574
|
+
|
|
575
|
+
const receive = Effect.fnUntraced(function*(message: McpSchema.JsonRpcMessage) {
|
|
576
|
+
if (isRequest(message)) return yield* write(replyToServer(message))
|
|
577
|
+
if (!isResponse(message)) return
|
|
578
|
+
// Without an ID the error cannot be correlated, so no pending request can be trusted.
|
|
579
|
+
if (message.id === undefined || message.id === null) {
|
|
580
|
+
return yield* fail(new ProtocolError({ description: "Server returned an uncorrelated JSON-RPC error" }))
|
|
581
|
+
}
|
|
582
|
+
const response = pending.get(message.id)
|
|
583
|
+
if (response !== undefined) yield* Deferred.succeed(response, message)
|
|
584
|
+
})
|
|
585
|
+
|
|
586
|
+
yield* Stream.fromQueue(input).pipe(
|
|
587
|
+
Stream.encodeText,
|
|
588
|
+
Stream.run(process.stdin),
|
|
589
|
+
Effect.catch((cause) => close(fail(new TransportError({ description: "MCP stdin failed", cause })))),
|
|
590
|
+
Effect.forkScoped
|
|
591
|
+
)
|
|
592
|
+
yield* Stream.runDrain(process.stderr).pipe(Effect.ignore, Effect.forkScoped)
|
|
593
|
+
const drained = yield* Deferred.make<void>()
|
|
594
|
+
let buffer = ""
|
|
595
|
+
yield* process.stdout.pipe(
|
|
596
|
+
Stream.decodeText(),
|
|
597
|
+
Stream.runForEach(Effect.fnUntraced(function*(chunk) {
|
|
598
|
+
buffer += chunk
|
|
599
|
+
let start = 0
|
|
600
|
+
let index: number
|
|
601
|
+
while ((index = buffer.indexOf("\n", start)) >= 0) {
|
|
602
|
+
const line = buffer.slice(start, index)
|
|
603
|
+
start = index + 1
|
|
604
|
+
if (line.trim() !== "") yield* receive(yield* parseMessage(line, maxBytes))
|
|
605
|
+
}
|
|
606
|
+
buffer = buffer.slice(start)
|
|
607
|
+
if (buffer.length > maxBytes) {
|
|
608
|
+
return yield* limitError("MCP message exceeds maxMessageBytes")
|
|
609
|
+
}
|
|
610
|
+
})),
|
|
611
|
+
Effect.mapError((cause) =>
|
|
612
|
+
isMcpClientError(cause)
|
|
613
|
+
? cause
|
|
614
|
+
: fail(new TransportError({ description: "MCP stdout failed", cause }))
|
|
615
|
+
),
|
|
616
|
+
Effect.andThen(Effect.fail(fail(new TransportError({ description: "MCP server closed stdout" })))),
|
|
617
|
+
Effect.catch(close),
|
|
618
|
+
Effect.ensuring(Deferred.succeed(drained, undefined)),
|
|
619
|
+
Effect.forkScoped
|
|
620
|
+
)
|
|
621
|
+
// Output written just before exit is delivered before pending requests fail.
|
|
622
|
+
yield* process.exitCode.pipe(
|
|
623
|
+
Effect.map((code) => `MCP process exited (${code})`),
|
|
624
|
+
Effect.orElseSucceed(() => "MCP process exited"),
|
|
625
|
+
Effect.tap(() => Deferred.await(drained).pipe(Effect.timeoutOption(CLOSE_TIMEOUT))),
|
|
626
|
+
Effect.flatMap((description) => close(fail(new TransportError({ description })))),
|
|
627
|
+
Effect.forkScoped
|
|
628
|
+
)
|
|
629
|
+
|
|
630
|
+
// Close stdin, then escalate to SIGTERM and SIGKILL if the server does not exit.
|
|
631
|
+
// https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle#stdio
|
|
632
|
+
yield* Effect.addFinalizer(Effect.fnUntraced(function*() {
|
|
633
|
+
yield* close(fail(new ClosedError({ description: "MCP transport closed" })))
|
|
634
|
+
yield* Queue.end(input)
|
|
635
|
+
const exited = yield* process.exitCode.pipe(Effect.timeoutOption(CLOSE_TIMEOUT), Effect.option)
|
|
636
|
+
if (Option.isNone(exited) || Option.isNone(exited.value)) {
|
|
637
|
+
yield* process.kill({ killSignal: "SIGTERM", forceKillAfter: Duration.toMillis(CLOSE_TIMEOUT) }).pipe(
|
|
638
|
+
Effect.ignore
|
|
639
|
+
)
|
|
640
|
+
}
|
|
641
|
+
}))
|
|
642
|
+
|
|
643
|
+
return {
|
|
644
|
+
[TransportTypeId]: TransportTypeId,
|
|
645
|
+
protocol: options.protocol,
|
|
646
|
+
isCallable: () => true,
|
|
647
|
+
notify: write,
|
|
648
|
+
request: Effect.fnUntraced(function*(message) {
|
|
649
|
+
const response = yield* Deferred.make<McpSchema.JsonRpcResponse>()
|
|
650
|
+
pending.set(message.id, response)
|
|
651
|
+
|
|
652
|
+
return yield* write(message).pipe(
|
|
653
|
+
Effect.andThen(Deferred.await(response)),
|
|
654
|
+
Effect.raceFirst(Deferred.await(failure)),
|
|
655
|
+
Effect.onInterrupt(() =>
|
|
656
|
+
message.method === "initialize"
|
|
657
|
+
? Effect.void
|
|
658
|
+
: Deferred.isDone(response).pipe(
|
|
659
|
+
Effect.flatMap((done) => done ? Effect.void : write(cancelled(message.id)).pipe(Effect.ignore))
|
|
660
|
+
)
|
|
661
|
+
),
|
|
662
|
+
Effect.ensuring(Effect.sync(() => pending.delete(message.id)))
|
|
663
|
+
)
|
|
664
|
+
})
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
)
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Provides a connected MCP client over stdio using the child process spawner.
|
|
671
|
+
*
|
|
672
|
+
* **Details**
|
|
673
|
+
*
|
|
674
|
+
* The layer scope owns the client and subprocess. The options are those of
|
|
675
|
+
* {@link make} and {@link stdio}.
|
|
676
|
+
*
|
|
677
|
+
* @see {@link layerHttp}
|
|
678
|
+
* @stability experimental
|
|
679
|
+
* @category layers
|
|
680
|
+
* @since 4.0.6
|
|
681
|
+
*/
|
|
682
|
+
export const layerStdio: (options: {
|
|
683
|
+
readonly name: string
|
|
684
|
+
readonly version: string
|
|
685
|
+
readonly title?: string | undefined
|
|
686
|
+
readonly description?: string | undefined
|
|
687
|
+
readonly websiteUrl?: string | undefined
|
|
688
|
+
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
689
|
+
readonly timeout?: Duration.Input | undefined
|
|
690
|
+
readonly command: ChildProcess.Command
|
|
691
|
+
readonly protocol: McpProtocol.ProtocolAdapter<ProtocolVersion>
|
|
692
|
+
readonly maxMessageBytes?: ByteSize.Input | undefined
|
|
693
|
+
}) => Layer.Layer<
|
|
694
|
+
McpClient,
|
|
695
|
+
McpClientError,
|
|
696
|
+
ChildProcessSpawner
|
|
697
|
+
> = (options) => Layer.effect(McpClient)(make(options)).pipe(Layer.provide(Layer.effect(Transport)(stdio(options))))
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Creates a Streamable HTTP transport with request-owned JSON or SSE responses.
|
|
701
|
+
*
|
|
702
|
+
* @stability experimental
|
|
703
|
+
* @category constructors
|
|
704
|
+
* @since 4.0.6
|
|
705
|
+
*/
|
|
706
|
+
export const http: (options: {
|
|
707
|
+
readonly url: string | URL
|
|
708
|
+
readonly protocol: McpProtocol.ProtocolAdapter<ProtocolVersion>
|
|
709
|
+
readonly headers?: Readonly<Record<string, string>> | undefined
|
|
710
|
+
readonly maxMessageBytes?: ByteSize.Input | undefined
|
|
711
|
+
}) => Effect.Effect<Transport, McpClientError, HttpClient.HttpClient | Scope.Scope> = Effect.fnUntraced(
|
|
712
|
+
function*(options: {
|
|
713
|
+
readonly url: string | URL
|
|
714
|
+
readonly protocol: Protocol
|
|
715
|
+
readonly headers?: Readonly<Record<string, string>> | undefined
|
|
716
|
+
readonly maxMessageBytes?: ByteSize.Input | undefined
|
|
717
|
+
}): Effect.fn.Return<Transport, McpClientError, HttpClient.HttpClient | Scope.Scope> {
|
|
718
|
+
const maxBytes = yield* messageLimit(options.maxMessageBytes)
|
|
719
|
+
const client = HttpClient.withScope(yield* HttpClient.HttpClient)
|
|
720
|
+
const modern = options.protocol.protocolVersion === "2026-07-28"
|
|
721
|
+
const closed = yield* Deferred.make<never, McpClientError>()
|
|
722
|
+
let failed: McpClientError | undefined
|
|
723
|
+
// Legacy servers may assign a session during initialization.
|
|
724
|
+
let session: string | undefined
|
|
725
|
+
|
|
726
|
+
const baseHeaders = {
|
|
727
|
+
...options.headers,
|
|
728
|
+
accept: "application/json, text/event-stream",
|
|
729
|
+
"mcp-protocol-version": options.protocol.protocolVersion
|
|
730
|
+
}
|
|
731
|
+
const headers = (): Record<string, string> =>
|
|
732
|
+
session === undefined ? baseHeaders : { ...baseHeaders, "mcp-session-id": session }
|
|
733
|
+
|
|
734
|
+
const httpError = Effect.fnUntraced(function*(response: HttpClientResponse.HttpClientResponse) {
|
|
735
|
+
// Error bodies may carry a JSON-RPC error without an ID, e.g. an unsupported protocol version.
|
|
736
|
+
const remote = mediaType(response) === "application/json"
|
|
737
|
+
? yield* readBody(response, maxBytes).pipe(
|
|
738
|
+
Effect.flatMap((text) => parseMessage(text, maxBytes)),
|
|
739
|
+
Effect.map((message) => "error" in message ? message.error : undefined),
|
|
740
|
+
Effect.orElseSucceed(() => undefined)
|
|
741
|
+
)
|
|
742
|
+
: undefined
|
|
743
|
+
return yield* fail(
|
|
744
|
+
new HttpError({
|
|
745
|
+
status: response.status,
|
|
746
|
+
code: remote?.code,
|
|
747
|
+
data: remote?.data,
|
|
748
|
+
description: remote?.message,
|
|
749
|
+
wwwAuthenticate: response.headers["www-authenticate"],
|
|
750
|
+
retryAfter: response.headers["retry-after"]
|
|
751
|
+
})
|
|
752
|
+
)
|
|
753
|
+
})
|
|
754
|
+
|
|
755
|
+
// Posts one message and returns the successful response, tracking legacy sessions.
|
|
756
|
+
const send = Effect.fnUntraced(function*(message: McpSchema.JsonRpcMessage, tool?: McpSchema.Tool) {
|
|
757
|
+
if (failed !== undefined) return yield* failed
|
|
758
|
+
const body = yield* encodeMessage(message, maxBytes)
|
|
759
|
+
const request = HttpClientRequest.post(options.url).pipe(
|
|
760
|
+
HttpClientRequest.setHeaders({ ...headers(), ...(modern ? yield* routingHeaders(message, tool) : {}) }),
|
|
761
|
+
HttpClientRequest.bodyText(body, "application/json")
|
|
762
|
+
)
|
|
763
|
+
const response = yield* client.execute(request).pipe(
|
|
764
|
+
// Clients using `filterStatusOk` surface error responses as failures.
|
|
765
|
+
Effect.catch((cause) =>
|
|
766
|
+
cause.response === undefined
|
|
767
|
+
? Effect.fail(fail(new TransportError({ description: "MCP HTTP request failed", cause })))
|
|
768
|
+
: Effect.succeed(cause.response)
|
|
769
|
+
)
|
|
770
|
+
)
|
|
771
|
+
|
|
772
|
+
// A legacy session ends when the server no longer recognizes its ID.
|
|
773
|
+
if (session !== undefined && response.status === 404) {
|
|
774
|
+
failed ??= fail(new ClosedError({ sessionExpired: true }))
|
|
775
|
+
return yield* failed
|
|
776
|
+
}
|
|
777
|
+
if (response.status < 200 || response.status >= 300) return yield* httpError(response)
|
|
778
|
+
if (!modern) session = response.headers["mcp-session-id"] ?? session
|
|
779
|
+
return response
|
|
780
|
+
})
|
|
781
|
+
|
|
782
|
+
const exchange = <A>(effect: Effect.Effect<A, unknown, Scope.Scope>) =>
|
|
783
|
+
effect.pipe(
|
|
784
|
+
Effect.mapError((cause) =>
|
|
785
|
+
isMcpClientError(cause)
|
|
786
|
+
? cause
|
|
787
|
+
: fail(new TransportError({ description: "Cannot read MCP response", cause }))
|
|
788
|
+
),
|
|
789
|
+
Effect.raceFirst(Deferred.await(closed)),
|
|
790
|
+
Effect.scoped
|
|
791
|
+
)
|
|
792
|
+
|
|
793
|
+
const notify = (message: McpSchema.JsonRpcNotification | McpSchema.JsonRpcResponse) =>
|
|
794
|
+
exchange(Effect.asVoid(send(message)))
|
|
795
|
+
|
|
796
|
+
const readResponse = Effect.fnUntraced(function*(
|
|
797
|
+
response: HttpClientResponse.HttpClientResponse,
|
|
798
|
+
request: McpSchema.JsonRpcRequest
|
|
799
|
+
) {
|
|
800
|
+
const match = Effect.fnUntraced(function*(message: McpSchema.JsonRpcMessage) {
|
|
801
|
+
if (isRequest(message)) {
|
|
802
|
+
yield* notify(replyToServer(message))
|
|
803
|
+
return undefined
|
|
804
|
+
}
|
|
805
|
+
if (!isResponse(message)) return undefined
|
|
806
|
+
// A response on this exchange belongs to its request; an error may omit the ID.
|
|
807
|
+
if (message.id !== request.id && !("error" in message && message.id == null)) {
|
|
808
|
+
return yield* fail(new ProtocolError({ description: "HTTP MCP response id does not match its request" }))
|
|
809
|
+
}
|
|
810
|
+
return message
|
|
811
|
+
})
|
|
812
|
+
|
|
813
|
+
switch (mediaType(response)) {
|
|
814
|
+
case "application/json": {
|
|
815
|
+
const message = yield* match(yield* parseMessage(yield* readBody(response, maxBytes), maxBytes))
|
|
816
|
+
if (message === undefined) break
|
|
817
|
+
return message
|
|
818
|
+
}
|
|
819
|
+
case "text/event-stream": {
|
|
820
|
+
const events: Array<string> = []
|
|
821
|
+
const parser = Sse.makeParser((event) => {
|
|
822
|
+
// Resumption is unsupported, so retry directives and event IDs are ignored.
|
|
823
|
+
if (event._tag === "Event" && event.data !== "") events.push(event.data)
|
|
824
|
+
}, { maxEventSize: maxBytes })
|
|
825
|
+
const message = yield* response.stream.pipe(
|
|
826
|
+
Stream.decodeText(),
|
|
827
|
+
Stream.flatMap((chunk) => {
|
|
828
|
+
const error = parser.feed(chunk)
|
|
829
|
+
const parsed = Stream.fromIterable(events.splice(0))
|
|
830
|
+
// Events before an oversized one can still complete the request.
|
|
831
|
+
return error === undefined ? parsed : parsed.pipe(
|
|
832
|
+
Stream.concat(Stream.fail(limitError("MCP SSE event exceeds maxMessageBytes")))
|
|
833
|
+
)
|
|
834
|
+
}),
|
|
835
|
+
Stream.mapEffect((data) => parseMessage(data, maxBytes).pipe(Effect.flatMap(match))),
|
|
836
|
+
Stream.filter(Predicate.isNotUndefined),
|
|
837
|
+
Stream.runHead
|
|
838
|
+
)
|
|
839
|
+
if (Option.isNone(message)) break
|
|
840
|
+
return message.value
|
|
841
|
+
}
|
|
842
|
+
default: {
|
|
843
|
+
return yield* fail(new ProtocolError({ description: "Unsupported MCP response Content-Type" }))
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
return yield* fail(new TransportError({ description: "MCP response ended before the terminal response" }))
|
|
847
|
+
})
|
|
848
|
+
|
|
849
|
+
yield* Effect.addFinalizer(Effect.fnUntraced(function*() {
|
|
850
|
+
failed ??= fail(new ClosedError({ description: "MCP HTTP transport closed" }))
|
|
851
|
+
yield* Deferred.fail(closed, failed)
|
|
852
|
+
if (session === undefined || failed.reason._tag !== "ClosedError" || failed.reason.sessionExpired) return
|
|
853
|
+
// Explicitly terminate a legacy session.
|
|
854
|
+
// https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#session-management
|
|
855
|
+
yield* client.execute(HttpClientRequest.delete(options.url).pipe(HttpClientRequest.setHeaders(headers()))).pipe(
|
|
856
|
+
Effect.scoped,
|
|
857
|
+
Effect.timeoutOption(CLOSE_TIMEOUT),
|
|
858
|
+
Effect.ignore
|
|
859
|
+
)
|
|
860
|
+
}))
|
|
861
|
+
|
|
862
|
+
return {
|
|
863
|
+
[TransportTypeId]: TransportTypeId,
|
|
864
|
+
protocol: options.protocol,
|
|
865
|
+
isCallable: (tool) => !modern || headerParameters(tool) !== undefined,
|
|
866
|
+
notify,
|
|
867
|
+
request: (message, tool) =>
|
|
868
|
+
exchange(
|
|
869
|
+
send(message, tool).pipe(
|
|
870
|
+
Effect.flatMap((response) =>
|
|
871
|
+
response.status === 202 || response.status === 204
|
|
872
|
+
? fail(new ProtocolError({ description: "MCP request received no response" }))
|
|
873
|
+
: readResponse(response, message)
|
|
874
|
+
)
|
|
875
|
+
)
|
|
876
|
+
).pipe(
|
|
877
|
+
// Modern servers treat a closed response stream as cancellation.
|
|
878
|
+
Effect.onInterrupt(() =>
|
|
879
|
+
modern || message.method === "initialize"
|
|
880
|
+
? Effect.void
|
|
881
|
+
: notify(cancelled(message.id)).pipe(Effect.timeoutOption(CLOSE_TIMEOUT), Effect.ignore)
|
|
882
|
+
)
|
|
883
|
+
)
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
)
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* Provides a connected MCP client over Streamable HTTP using the HTTP client.
|
|
890
|
+
*
|
|
891
|
+
* **Details**
|
|
892
|
+
*
|
|
893
|
+
* The layer scope owns the client and connection. The options are those of
|
|
894
|
+
* {@link make} and {@link http}.
|
|
895
|
+
*
|
|
896
|
+
* **Example** (Providing an HTTP client connection)
|
|
897
|
+
*
|
|
898
|
+
* ```ts import.meta.vitest
|
|
899
|
+
* import { Layer } from "effect"
|
|
900
|
+
* import { McpClient, McpProtocol } from "effect/ai"
|
|
901
|
+
* import { FetchHttpClient } from "effect/http"
|
|
902
|
+
*
|
|
903
|
+
* const ClientLayer = McpClient.layerHttp({
|
|
904
|
+
* name: "report-workflow",
|
|
905
|
+
* version: "1.0.0",
|
|
906
|
+
* protocol: McpProtocol.v2026_07_28,
|
|
907
|
+
* url: "http://localhost:3000/mcp"
|
|
908
|
+
* }).pipe(Layer.provide(FetchHttpClient.layer))
|
|
909
|
+
* ```
|
|
910
|
+
*
|
|
911
|
+
* @see {@link layerStdio}
|
|
912
|
+
* @stability experimental
|
|
913
|
+
* @category layers
|
|
914
|
+
* @since 4.0.6
|
|
915
|
+
*/
|
|
916
|
+
export const layerHttp: (options: {
|
|
917
|
+
readonly name: string
|
|
918
|
+
readonly version: string
|
|
919
|
+
readonly title?: string | undefined
|
|
920
|
+
readonly description?: string | undefined
|
|
921
|
+
readonly websiteUrl?: string | undefined
|
|
922
|
+
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
923
|
+
readonly timeout?: Duration.Input | undefined
|
|
924
|
+
readonly url: string | URL
|
|
925
|
+
readonly protocol: McpProtocol.ProtocolAdapter<ProtocolVersion>
|
|
926
|
+
readonly headers?: Readonly<Record<string, string>> | undefined
|
|
927
|
+
readonly maxMessageBytes?: ByteSize.Input | undefined
|
|
928
|
+
}) => Layer.Layer<
|
|
929
|
+
McpClient,
|
|
930
|
+
McpClientError,
|
|
931
|
+
HttpClient.HttpClient
|
|
932
|
+
> = (options) => Layer.effect(McpClient)(make(options)).pipe(Layer.provide(Layer.effect(Transport)(http(options))))
|
|
933
|
+
|
|
934
|
+
// =============================================================================
|
|
935
|
+
// Internal
|
|
936
|
+
// =============================================================================
|
|
937
|
+
|
|
938
|
+
const TypeId = "~effect/ai/McpClient" as const
|
|
939
|
+
const TransportTypeId = "~effect/ai/McpClient/Transport" as const
|
|
940
|
+
const DEFAULT_MAX_MESSAGE_BYTES = ByteSize.mebibytes(16)
|
|
941
|
+
const DEFAULT_TIMEOUT = Duration.seconds(60)
|
|
942
|
+
const CLOSE_TIMEOUT = Duration.seconds(5)
|
|
943
|
+
const MAX_DISCOVERY_PAGES = 100
|
|
944
|
+
const MAX_DISCOVERY_ITEMS = 10_000
|
|
945
|
+
const HEADER_TOKEN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/
|
|
946
|
+
const encoder = new TextEncoder()
|
|
947
|
+
const decoder = new TextDecoder()
|
|
948
|
+
|
|
949
|
+
type Protocol = McpProtocol.ProtocolAdapter<ProtocolVersion>
|
|
950
|
+
|
|
951
|
+
type Options = Parameters<typeof make>[0]
|
|
952
|
+
|
|
953
|
+
type Capability = "tools" | "prompts" | "resources"
|
|
954
|
+
|
|
955
|
+
interface CallOptions {
|
|
956
|
+
readonly timeout?: Duration.Input | undefined
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
interface InitializeResult {
|
|
960
|
+
readonly protocolVersion?: string
|
|
961
|
+
readonly supportedVersions?: ReadonlyArray<string>
|
|
962
|
+
readonly capabilities: unknown
|
|
963
|
+
readonly serverInfo?: unknown
|
|
964
|
+
readonly instructions?: string
|
|
965
|
+
readonly _meta?: Record<string, unknown>
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
type ListResult<K extends string, A> = Record<K, ReadonlyArray<A>> & { readonly nextCursor?: string }
|
|
969
|
+
const fail = (reason: McpClientErrorReason) => new McpClientError({ reason })
|
|
970
|
+
const limitError = (description: string) => fail(new LimitError({ description }))
|
|
971
|
+
|
|
972
|
+
const validationError = (cause: Schema.SchemaError) =>
|
|
973
|
+
fail(new ValidationError({ description: "Invalid MCP payload", cause }))
|
|
974
|
+
|
|
975
|
+
const isRecord = Predicate.isReadonlyObject
|
|
976
|
+
const decodeMessage = Schema.decodeUnknownEffect(McpSchema.JsonRpcMessage, { onExcessProperty: "error" })
|
|
977
|
+
|
|
978
|
+
const decodeVersionRejection = Schema.decodeUnknownOption(Schema.Struct({
|
|
979
|
+
requested: Schema.String,
|
|
980
|
+
supported: Schema.Array(Schema.String)
|
|
981
|
+
}))
|
|
982
|
+
|
|
983
|
+
const decodeServerCapabilities = Schema.decodeUnknownEffect(McpSchema.ServerCapabilities)
|
|
984
|
+
const decodeImplementation = Schema.decodeUnknownEffect(McpSchema.Implementation)
|
|
985
|
+
const encodeImplementation = Schema.encodeSync(McpSchema.Implementation)
|
|
986
|
+
|
|
987
|
+
// The protocol payload codec validates argument values; the toolkit only checks for an object.
|
|
988
|
+
const decodeToolArguments = Schema.decodeUnknownEffect(Schema.Record(Schema.String, Schema.Unknown))
|
|
989
|
+
|
|
990
|
+
const decodeUnknown = (schema: Schema.Constraint, value: unknown) =>
|
|
991
|
+
Schema.decodeUnknownEffect(schema as Schema.ConstraintCodec<unknown, unknown>)(value).pipe(
|
|
992
|
+
Effect.mapError(validationError)
|
|
993
|
+
)
|
|
994
|
+
|
|
995
|
+
const publicRpcs: ReadonlyMap<string, { readonly successSchema: Schema.Constraint }> =
|
|
996
|
+
McpSchema.ClientRequestRpcs.requests
|
|
997
|
+
|
|
998
|
+
// Tools that require task-augmented execution cannot be called without the tasks extension.
|
|
999
|
+
const requiresTasks = (tool: unknown) =>
|
|
1000
|
+
isRecord(tool) && isRecord(tool.execution) && tool.execution.taskSupport === "required"
|
|
1001
|
+
|
|
1002
|
+
const messageLimit = (input: ByteSize.Input = DEFAULT_MAX_MESSAGE_BYTES) => {
|
|
1003
|
+
const bytes = Option.flatMap(ByteSize.fromInput(input), ByteSize.toNumber)
|
|
1004
|
+
return Option.isSome(bytes) && bytes.value > 0
|
|
1005
|
+
? Effect.succeed(bytes.value)
|
|
1006
|
+
: Effect.fail(fail(new ConfigurationError({ description: "maxMessageBytes must be a positive safe integer" })))
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
const encodeMessage = Effect.fnUntraced(function*(message: McpSchema.JsonRpcMessage, maxBytes: number) {
|
|
1010
|
+
const json = yield* Effect.try({
|
|
1011
|
+
try: () => JSON.stringify(message),
|
|
1012
|
+
catch: (cause) => fail(new TransportError({ description: "Cannot encode MCP message", cause }))
|
|
1013
|
+
})
|
|
1014
|
+
if (encoder.encode(json).length > maxBytes) {
|
|
1015
|
+
return yield* limitError("MCP message exceeds maxMessageBytes")
|
|
1016
|
+
}
|
|
1017
|
+
return json
|
|
1018
|
+
})
|
|
1019
|
+
|
|
1020
|
+
const parseMessage = Effect.fnUntraced(function*(text: string, maxBytes: number) {
|
|
1021
|
+
if (encoder.encode(text).length > maxBytes) {
|
|
1022
|
+
return yield* limitError("MCP message exceeds maxMessageBytes")
|
|
1023
|
+
}
|
|
1024
|
+
const json = yield* Effect.try({
|
|
1025
|
+
try: () => JSON.parse(text) as unknown,
|
|
1026
|
+
catch: (cause) => fail(new ProtocolError({ description: "Invalid MCP JSON", cause }))
|
|
1027
|
+
})
|
|
1028
|
+
return yield* decodeMessage(json).pipe(
|
|
1029
|
+
Effect.mapError((cause) => fail(new ProtocolError({ description: "Invalid JSON-RPC message", cause })))
|
|
1030
|
+
)
|
|
1031
|
+
})
|
|
1032
|
+
|
|
1033
|
+
const isRequest = (message: McpSchema.JsonRpcMessage): message is McpSchema.JsonRpcRequest =>
|
|
1034
|
+
"method" in message && "id" in message
|
|
1035
|
+
|
|
1036
|
+
const isResponse = (message: McpSchema.JsonRpcMessage): message is McpSchema.JsonRpcResponse => !("method" in message)
|
|
1037
|
+
|
|
1038
|
+
// The client advertises no capabilities, so it answers pings and declines every other server request.
|
|
1039
|
+
const replyToServer = (request: McpSchema.JsonRpcRequest): McpSchema.JsonRpcResponse =>
|
|
1040
|
+
request.method === "ping"
|
|
1041
|
+
? { jsonrpc: "2.0", id: request.id, result: {} }
|
|
1042
|
+
: {
|
|
1043
|
+
jsonrpc: "2.0",
|
|
1044
|
+
id: request.id,
|
|
1045
|
+
error: { code: McpSchema.METHOD_NOT_FOUND_ERROR_CODE, message: `Unsupported MCP method: ${request.method}` }
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
const cancelled = (id: McpSchema.RequestId): McpSchema.JsonRpcNotification => ({
|
|
1049
|
+
jsonrpc: "2.0",
|
|
1050
|
+
method: "notifications/cancelled",
|
|
1051
|
+
params: { requestId: id }
|
|
1052
|
+
})
|
|
1053
|
+
|
|
1054
|
+
// =============================================================================
|
|
1055
|
+
// Internal: Streamable HTTP
|
|
1056
|
+
// =============================================================================
|
|
1057
|
+
|
|
1058
|
+
const mediaType = (response: HttpClientResponse.HttpClientResponse) =>
|
|
1059
|
+
response.headers["content-type"]?.split(";", 1)[0].trim().toLowerCase()
|
|
1060
|
+
|
|
1061
|
+
const readBody = (response: HttpClientResponse.HttpClientResponse, maxBytes: number) =>
|
|
1062
|
+
response.stream.pipe(
|
|
1063
|
+
Stream.mapError((cause) => fail(new TransportError({ description: "Cannot read MCP response", cause }))),
|
|
1064
|
+
Stream.limitBytes(maxBytes, () => Stream.fail(limitError("MCP response exceeds maxMessageBytes"))),
|
|
1065
|
+
Stream.mkUint8Array,
|
|
1066
|
+
Effect.map((bytes) => decoder.decode(bytes))
|
|
1067
|
+
)
|
|
1068
|
+
|
|
1069
|
+
// Values that are not plain visible ASCII are sent Base64 encoded.
|
|
1070
|
+
// https://modelcontextprotocol.io/specification/2026-07-28/basic/transports#custom-headers-from-tool-parameters
|
|
1071
|
+
const headerValue = (value: string) =>
|
|
1072
|
+
/^[\x20-\x7e]*$/.test(value) && value.trim() === value &&
|
|
1073
|
+
!(value.startsWith(BASE64_SENTINEL_PREFIX) && value.endsWith(BASE64_SENTINEL_SUFFIX))
|
|
1074
|
+
? value
|
|
1075
|
+
: `${BASE64_SENTINEL_PREFIX}${Base64.encode(value)}${BASE64_SENTINEL_SUFFIX}`
|
|
1076
|
+
|
|
1077
|
+
interface HeaderParameter {
|
|
1078
|
+
readonly path: ReadonlyArray<string>
|
|
1079
|
+
readonly header: string
|
|
1080
|
+
readonly type: string
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// JSON Schema keywords whose values are schemas, maps of schemas or arrays of schemas.
|
|
1084
|
+
const SCHEMA_KEYWORDS = new Set([
|
|
1085
|
+
"additionalProperties",
|
|
1086
|
+
"unevaluatedProperties",
|
|
1087
|
+
"propertyNames",
|
|
1088
|
+
"items",
|
|
1089
|
+
"additionalItems",
|
|
1090
|
+
"unevaluatedItems",
|
|
1091
|
+
"contains",
|
|
1092
|
+
"not",
|
|
1093
|
+
"if",
|
|
1094
|
+
"then",
|
|
1095
|
+
"else",
|
|
1096
|
+
"contentSchema"
|
|
1097
|
+
])
|
|
1098
|
+
|
|
1099
|
+
const SCHEMA_MAP_KEYWORDS = new Set([
|
|
1100
|
+
"properties",
|
|
1101
|
+
"patternProperties",
|
|
1102
|
+
"$defs",
|
|
1103
|
+
"definitions",
|
|
1104
|
+
"dependentSchemas",
|
|
1105
|
+
"dependencies"
|
|
1106
|
+
])
|
|
1107
|
+
|
|
1108
|
+
const SCHEMA_ARRAY_KEYWORDS = new Set(["allOf", "anyOf", "oneOf", "prefixItems", "items"])
|
|
1109
|
+
|
|
1110
|
+
// Collects `x-mcp-header` annotations along chains of `properties` keys, or
|
|
1111
|
+
// returns undefined when an annotation is invalid or found anywhere else.
|
|
1112
|
+
// https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http#schema-extension
|
|
1113
|
+
const headerParameters = (tool: McpSchema.Tool): ReadonlyArray<HeaderParameter> | undefined => {
|
|
1114
|
+
const parameters: Array<HeaderParameter> = []
|
|
1115
|
+
const names = new Set<string>()
|
|
1116
|
+
|
|
1117
|
+
// `path` is undefined once the traversal leaves a properties-only chain.
|
|
1118
|
+
const visit = (schema: unknown, path: ReadonlyArray<string> | undefined): boolean => {
|
|
1119
|
+
if (!isRecord(schema)) return true
|
|
1120
|
+
const name = schema["x-mcp-header"]
|
|
1121
|
+
if (name !== undefined) {
|
|
1122
|
+
if (
|
|
1123
|
+
path === undefined || path.length === 0 || typeof name !== "string" || !HEADER_TOKEN.test(name) ||
|
|
1124
|
+
names.has(name.toLowerCase()) || !["string", "integer", "boolean"].includes(schema.type as string)
|
|
1125
|
+
) return false
|
|
1126
|
+
names.add(name.toLowerCase())
|
|
1127
|
+
parameters.push({ path, header: `mcp-param-${name.toLowerCase()}`, type: schema.type as string })
|
|
1128
|
+
}
|
|
1129
|
+
return Object.entries(schema).every(([keyword, value]) => {
|
|
1130
|
+
if (SCHEMA_MAP_KEYWORDS.has(keyword) && isRecord(value)) {
|
|
1131
|
+
return Object.entries(value).every(([key, child]) =>
|
|
1132
|
+
visit(child, keyword === "properties" && path !== undefined ? [...path, key] : undefined)
|
|
1133
|
+
)
|
|
1134
|
+
}
|
|
1135
|
+
if (Array.isArray(value)) {
|
|
1136
|
+
return !SCHEMA_ARRAY_KEYWORDS.has(keyword) || value.every((child) => visit(child, undefined))
|
|
1137
|
+
}
|
|
1138
|
+
return !SCHEMA_KEYWORDS.has(keyword) || visit(value, undefined)
|
|
1139
|
+
})
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
return visit(tool.inputSchema, []) ? parameters : undefined
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
const routingHeaders = Effect.fnUntraced(function*(message: McpSchema.JsonRpcMessage, tool?: McpSchema.Tool) {
|
|
1146
|
+
if (!("method" in message)) return {}
|
|
1147
|
+
const headers: Record<string, string> = { "mcp-method": message.method }
|
|
1148
|
+
const params = message.params ?? {}
|
|
1149
|
+
const name = message.method === "resources/read" ? params.uri : params.name
|
|
1150
|
+
if (
|
|
1151
|
+
typeof name === "string" &&
|
|
1152
|
+
(message.method === "tools/call" || message.method === "prompts/get" || message.method === "resources/read")
|
|
1153
|
+
) {
|
|
1154
|
+
headers["mcp-name"] = headerValue(name)
|
|
1155
|
+
}
|
|
1156
|
+
if (message.method !== "tools/call") return headers
|
|
1157
|
+
|
|
1158
|
+
const parameters = tool === undefined ? undefined : headerParameters(tool)
|
|
1159
|
+
if (parameters === undefined) {
|
|
1160
|
+
return yield* fail(new UnsupportedError({ description: "Tool has invalid x-mcp-header annotations" }))
|
|
1161
|
+
}
|
|
1162
|
+
for (const { header, path, type } of parameters) {
|
|
1163
|
+
let value: unknown = params.arguments
|
|
1164
|
+
for (const key of path) value = isRecord(value) && Object.hasOwn(value, key) ? value[key] : undefined
|
|
1165
|
+
if (value === undefined || value === null) continue
|
|
1166
|
+
if (type === "integer" ? !Number.isSafeInteger(value) : typeof value !== type) {
|
|
1167
|
+
return yield* fail(new ValidationError({ description: `Invalid value for MCP header parameter ${header}` }))
|
|
1168
|
+
}
|
|
1169
|
+
headers[header] = headerValue(String(value))
|
|
1170
|
+
}
|
|
1171
|
+
return headers
|
|
1172
|
+
})
|
|
1173
|
+
|
|
1174
|
+
// =============================================================================
|
|
1175
|
+
// Internal: Toolkit
|
|
1176
|
+
// =============================================================================
|
|
1177
|
+
|
|
1178
|
+
const toText = (result: McpSchema.CallToolResult): Effect.Effect<string, McpClientError> => {
|
|
1179
|
+
const unsupported = (content: string) =>
|
|
1180
|
+
Effect.fail(
|
|
1181
|
+
fail(new UnsupportedError({ description: `MCP ${content} requires an application text converter`, result }))
|
|
1182
|
+
)
|
|
1183
|
+
const parts: Array<string> = []
|
|
1184
|
+
for (const block of result.content) {
|
|
1185
|
+
switch (block.type) {
|
|
1186
|
+
case "text": {
|
|
1187
|
+
parts.push(block.text)
|
|
1188
|
+
break
|
|
1189
|
+
}
|
|
1190
|
+
case "resource_link": {
|
|
1191
|
+
parts.push(
|
|
1192
|
+
`${block.title ?? block.name}: ${block.uri}${block.description === undefined ? "" : `\n${block.description}`}`
|
|
1193
|
+
)
|
|
1194
|
+
break
|
|
1195
|
+
}
|
|
1196
|
+
case "resource": {
|
|
1197
|
+
if (!("text" in block.resource)) return unsupported("binary resources")
|
|
1198
|
+
parts.push(block.resource.text)
|
|
1199
|
+
break
|
|
1200
|
+
}
|
|
1201
|
+
default: {
|
|
1202
|
+
return unsupported(`${block.type} content`)
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
return Effect.succeed(
|
|
1207
|
+
parts.length === 0 && result.structuredContent !== undefined
|
|
1208
|
+
? JSON.stringify(result.structuredContent)
|
|
1209
|
+
: parts.join("\n")
|
|
1210
|
+
)
|
|
1211
|
+
}
|