effect 4.0.6 → 4.1.0
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/README.md +1 -1
- package/dist/Arbitrary.d.ts +10 -2
- package/dist/Arbitrary.d.ts.map +1 -1
- package/dist/Arbitrary.js +2 -1
- package/dist/Arbitrary.js.map +1 -1
- package/dist/BigDecimal.d.ts.map +1 -1
- package/dist/BigDecimal.js +3 -0
- package/dist/BigDecimal.js.map +1 -1
- package/dist/Channel.d.ts +12 -6
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +30 -9
- package/dist/Channel.js.map +1 -1
- package/dist/Config.d.ts +7 -1
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js.map +1 -1
- package/dist/Context.d.ts +18 -1
- package/dist/Context.d.ts.map +1 -1
- package/dist/Context.js +27 -8
- package/dist/Context.js.map +1 -1
- package/dist/Cron.d.ts +81 -11
- package/dist/Cron.d.ts.map +1 -1
- package/dist/Cron.js +101 -26
- package/dist/Cron.js.map +1 -1
- package/dist/Data.d.ts +54 -235
- package/dist/Data.d.ts.map +1 -1
- package/dist/Data.js.map +1 -1
- package/dist/Duration.d.ts +78 -0
- package/dist/Duration.d.ts.map +1 -1
- package/dist/Duration.js +123 -0
- package/dist/Duration.js.map +1 -1
- package/dist/Effect.d.ts +165 -8
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +12 -2
- package/dist/Effect.js.map +1 -1
- package/dist/Equal.d.ts.map +1 -1
- package/dist/Equal.js +8 -1
- package/dist/Equal.js.map +1 -1
- package/dist/Exit.d.ts +3 -3
- package/dist/Exit.d.ts.map +1 -1
- package/dist/Exit.js.map +1 -1
- package/dist/FileSystem.d.ts +59 -4
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js +9 -2
- package/dist/FileSystem.js.map +1 -1
- package/dist/Formatter.d.ts.map +1 -1
- package/dist/Formatter.js +27 -13
- package/dist/Formatter.js.map +1 -1
- package/dist/Glob.d.ts +165 -0
- package/dist/Glob.d.ts.map +1 -0
- package/dist/Glob.js +127 -0
- package/dist/Glob.js.map +1 -0
- package/dist/Hash.d.ts.map +1 -1
- package/dist/Hash.js +4 -1
- package/dist/Hash.js.map +1 -1
- package/dist/JsonPatch.js +4 -0
- package/dist/JsonPatch.js.map +1 -1
- package/dist/JsonSchema.d.ts.map +1 -1
- package/dist/JsonSchema.js +13 -40
- package/dist/JsonSchema.js.map +1 -1
- package/dist/Match.d.ts +86 -0
- package/dist/Match.d.ts.map +1 -1
- package/dist/Match.js +72 -0
- package/dist/Match.js.map +1 -1
- package/dist/Metric.d.ts +3 -3
- package/dist/MutableList.d.ts +5 -2
- package/dist/MutableList.d.ts.map +1 -1
- package/dist/MutableList.js +7 -5
- package/dist/MutableList.js.map +1 -1
- package/dist/MutableRef.d.ts.map +1 -1
- package/dist/MutableRef.js +7 -0
- package/dist/MutableRef.js.map +1 -1
- package/dist/PartitionedSemaphore.d.ts +2 -1
- package/dist/PartitionedSemaphore.d.ts.map +1 -1
- package/dist/PartitionedSemaphore.js +22 -12
- package/dist/PartitionedSemaphore.js.map +1 -1
- package/dist/Pool.d.ts +51 -0
- package/dist/Pool.d.ts.map +1 -1
- package/dist/Pool.js +136 -36
- package/dist/Pool.js.map +1 -1
- package/dist/PubSub.d.ts.map +1 -1
- package/dist/PubSub.js +5 -6
- package/dist/PubSub.js.map +1 -1
- package/dist/Random.d.ts.map +1 -1
- package/dist/Random.js +3 -3
- package/dist/Random.js.map +1 -1
- package/dist/RcMap.d.ts.map +1 -1
- package/dist/RcMap.js +8 -2
- package/dist/RcMap.js.map +1 -1
- package/dist/Ref.d.ts.map +1 -1
- package/dist/Ref.js +8 -0
- package/dist/Ref.js.map +1 -1
- package/dist/Schedule.d.ts +18 -1
- package/dist/Schedule.d.ts.map +1 -1
- package/dist/Schedule.js +8 -3
- package/dist/Schedule.js.map +1 -1
- package/dist/Schema.d.ts +690 -49
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +687 -28
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaAST.d.ts +4 -2
- package/dist/SchemaAST.d.ts.map +1 -1
- package/dist/SchemaAST.js +14 -17
- package/dist/SchemaAST.js.map +1 -1
- package/dist/SchemaGetter.d.ts +6 -1
- package/dist/SchemaGetter.d.ts.map +1 -1
- package/dist/SchemaGetter.js +22 -11
- package/dist/SchemaGetter.js.map +1 -1
- package/dist/SchemaParser.d.ts.map +1 -1
- package/dist/SchemaParser.js +48 -22
- package/dist/SchemaParser.js.map +1 -1
- package/dist/SchemaRepresentation.d.ts +33 -10
- package/dist/SchemaRepresentation.d.ts.map +1 -1
- package/dist/SchemaRepresentation.js +39 -13
- package/dist/SchemaRepresentation.js.map +1 -1
- package/dist/SchemaTransformation.d.ts +12 -4
- package/dist/SchemaTransformation.d.ts.map +1 -1
- package/dist/SchemaTransformation.js +15 -5
- package/dist/SchemaTransformation.js.map +1 -1
- package/dist/ScopedCache.d.ts.map +1 -1
- package/dist/ScopedCache.js +5 -7
- package/dist/ScopedCache.js.map +1 -1
- package/dist/Semaphore.d.ts +130 -0
- package/dist/Semaphore.d.ts.map +1 -1
- package/dist/Semaphore.js +94 -35
- package/dist/Semaphore.js.map +1 -1
- package/dist/Sink.d.ts.map +1 -1
- package/dist/Sink.js +7 -2
- package/dist/Sink.js.map +1 -1
- package/dist/Stream.d.ts +13 -4
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +31 -10
- package/dist/Stream.js.map +1 -1
- package/dist/String.d.ts +3 -0
- package/dist/String.d.ts.map +1 -1
- package/dist/String.js +3 -0
- package/dist/String.js.map +1 -1
- package/dist/Terminal.d.ts +18 -1
- package/dist/Terminal.d.ts.map +1 -1
- package/dist/Terminal.js +1 -1
- package/dist/Terminal.js.map +1 -1
- package/dist/Tracer.d.ts +11 -1
- package/dist/Tracer.d.ts.map +1 -1
- package/dist/Tracer.js +6 -1
- package/dist/Tracer.js.map +1 -1
- package/dist/ai/AiError.d.ts +43 -116
- package/dist/ai/AiError.d.ts.map +1 -1
- package/dist/ai/AiError.js +53 -72
- package/dist/ai/AiError.js.map +1 -1
- package/dist/ai/Decision.d.ts +196 -15
- package/dist/ai/Decision.d.ts.map +1 -1
- package/dist/ai/Decision.js +130 -0
- package/dist/ai/Decision.js.map +1 -1
- package/dist/ai/DecisionModel.d.ts +54 -13
- package/dist/ai/DecisionModel.d.ts.map +1 -1
- package/dist/ai/DecisionModel.js +123 -12
- package/dist/ai/DecisionModel.js.map +1 -1
- package/dist/ai/LanguageModel.d.ts.map +1 -1
- package/dist/ai/LanguageModel.js +9 -0
- package/dist/ai/LanguageModel.js.map +1 -1
- package/dist/ai/McpSchema.d.ts +110 -110
- package/dist/ai/McpSchema.d.ts.map +1 -1
- package/dist/ai/McpServer.d.ts +630 -29
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +583 -131
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/McpTest.d.ts +130 -0
- package/dist/ai/McpTest.d.ts.map +1 -0
- package/dist/ai/McpTest.js +237 -0
- package/dist/ai/McpTest.js.map +1 -0
- package/dist/ai/Prompt.d.ts +52 -0
- package/dist/ai/Prompt.d.ts.map +1 -1
- package/dist/ai/Prompt.js +38 -0
- package/dist/ai/Prompt.js.map +1 -1
- package/dist/ai/Response.d.ts +17 -28
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js +5 -10
- package/dist/ai/Response.js.map +1 -1
- package/dist/ai/Tool.d.ts +43 -1
- package/dist/ai/Tool.d.ts.map +1 -1
- package/dist/ai/Tool.js +5 -2
- package/dist/ai/Tool.js.map +1 -1
- package/dist/ai/Toolkit.d.ts.map +1 -1
- package/dist/ai/Toolkit.js +8 -1
- package/dist/ai/Toolkit.js.map +1 -1
- package/dist/ai/index.d.ts +5 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +5 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/internal/mcpCore.js +17 -12
- package/dist/ai/internal/mcpCore.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js +18 -10
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
- package/dist/ai/internal/mcpProtocol.js +13 -0
- package/dist/ai/internal/mcpProtocol.js.map +1 -1
- package/dist/ai/internal/mcpRuntime.js +5 -3
- package/dist/ai/internal/mcpRuntime.js.map +1 -1
- package/dist/ai/internal/mcpStatefulRuntime.js +6 -1
- package/dist/ai/internal/mcpStatefulRuntime.js.map +1 -1
- package/dist/cli/Argument.d.ts +21 -0
- package/dist/cli/Argument.d.ts.map +1 -1
- package/dist/cli/Argument.js +7 -0
- package/dist/cli/Argument.js.map +1 -1
- package/dist/cli/CliError.d.ts +78 -0
- package/dist/cli/CliError.d.ts.map +1 -1
- package/dist/cli/CliError.js +65 -3
- package/dist/cli/CliError.js.map +1 -1
- package/dist/cli/CliOutput.d.ts +220 -7
- package/dist/cli/CliOutput.d.ts.map +1 -1
- package/dist/cli/CliOutput.js +156 -43
- package/dist/cli/CliOutput.js.map +1 -1
- package/dist/cli/Command.d.ts +47 -16
- package/dist/cli/Command.d.ts.map +1 -1
- package/dist/cli/Command.js +67 -29
- package/dist/cli/Command.js.map +1 -1
- package/dist/cli/Completions.d.ts +58 -0
- package/dist/cli/Completions.d.ts.map +1 -1
- package/dist/cli/Completions.js +49 -9
- package/dist/cli/Completions.js.map +1 -1
- package/dist/cli/Flag.d.ts +122 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +42 -0
- package/dist/cli/Flag.js.map +1 -1
- package/dist/cli/GlobalFlag.d.ts.map +1 -1
- package/dist/cli/GlobalFlag.js +15 -7
- package/dist/cli/GlobalFlag.js.map +1 -1
- package/dist/cli/HelpDoc.d.ts +15 -1
- package/dist/cli/HelpDoc.d.ts.map +1 -1
- package/dist/cli/Param.d.ts +15 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +23 -2
- package/dist/cli/Param.js.map +1 -1
- package/dist/cli/Primitive.d.ts +14 -0
- package/dist/cli/Primitive.d.ts.map +1 -1
- package/dist/cli/Primitive.js +15 -1
- package/dist/cli/Primitive.js.map +1 -1
- package/dist/cli/Prompt.d.ts +1 -0
- package/dist/cli/Prompt.d.ts.map +1 -1
- package/dist/cli/Prompt.js +1 -0
- package/dist/cli/Prompt.js.map +1 -1
- package/dist/cli/TerminalCapabilities.d.ts +3 -2
- package/dist/cli/TerminalCapabilities.d.ts.map +1 -1
- package/dist/cli/TerminalCapabilities.js +3 -1
- package/dist/cli/TerminalCapabilities.js.map +1 -1
- package/dist/cli/internal/completions/bash.js +73 -27
- package/dist/cli/internal/completions/bash.js.map +1 -1
- package/dist/cli/internal/help.d.ts.map +1 -1
- package/dist/cli/internal/help.js +17 -10
- package/dist/cli/internal/help.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +45 -10
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts +23 -45
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +6 -7
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +151 -49
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/ShardingConfig.d.ts +76 -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/SingleRunner.d.ts +3 -3
- package/dist/cluster/SingleRunner.d.ts.map +1 -1
- package/dist/cluster/SingleRunner.js +1 -1
- package/dist/cluster/Snowflake.d.ts.map +1 -1
- package/dist/cluster/Snowflake.js +3 -7
- package/dist/cluster/Snowflake.js.map +1 -1
- package/dist/cluster/SqlMessageStorage.d.ts +37 -6
- package/dist/cluster/SqlMessageStorage.d.ts.map +1 -1
- package/dist/cluster/SqlMessageStorage.js +34 -7
- package/dist/cluster/SqlMessageStorage.js.map +1 -1
- package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
- package/dist/cluster/SqlRunnerStorage.js +109 -46
- package/dist/cluster/SqlRunnerStorage.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +54 -20
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/crypto/Aead.d.ts +322 -0
- package/dist/crypto/Aead.d.ts.map +1 -0
- package/dist/crypto/Aead.js +331 -0
- package/dist/crypto/Aead.js.map +1 -0
- package/dist/crypto/Cipher.d.ts +235 -0
- package/dist/crypto/Cipher.d.ts.map +1 -0
- package/dist/crypto/Cipher.js +233 -0
- package/dist/crypto/Cipher.js.map +1 -0
- package/dist/crypto/CryptoError.d.ts +212 -0
- package/dist/crypto/CryptoError.d.ts.map +1 -0
- package/dist/crypto/CryptoError.js +202 -0
- package/dist/crypto/CryptoError.js.map +1 -0
- package/dist/crypto/Digest.d.ts +143 -0
- package/dist/crypto/Digest.d.ts.map +1 -0
- package/dist/crypto/Digest.js +146 -0
- package/dist/crypto/Digest.js.map +1 -0
- package/dist/crypto/Kdf.d.ts +220 -0
- package/dist/crypto/Kdf.d.ts.map +1 -0
- package/dist/crypto/Kdf.js +212 -0
- package/dist/crypto/Kdf.js.map +1 -0
- package/dist/crypto/KeyAgreement.d.ts +323 -0
- package/dist/crypto/KeyAgreement.d.ts.map +1 -0
- package/dist/crypto/KeyAgreement.js +303 -0
- package/dist/crypto/KeyAgreement.js.map +1 -0
- package/dist/crypto/KeyFormat.d.ts +309 -0
- package/dist/crypto/KeyFormat.d.ts.map +1 -0
- package/dist/crypto/KeyFormat.js +556 -0
- package/dist/crypto/KeyFormat.js.map +1 -0
- package/dist/crypto/KeyWrap.d.ts +389 -0
- package/dist/crypto/KeyWrap.d.ts.map +1 -0
- package/dist/crypto/KeyWrap.js +381 -0
- package/dist/crypto/KeyWrap.js.map +1 -0
- package/dist/crypto/Mac.d.ts +277 -0
- package/dist/crypto/Mac.d.ts.map +1 -0
- package/dist/crypto/Mac.js +288 -0
- package/dist/crypto/Mac.js.map +1 -0
- package/dist/crypto/SecureRandom.d.ts +340 -0
- package/dist/crypto/SecureRandom.d.ts.map +1 -0
- package/dist/crypto/SecureRandom.js +257 -0
- package/dist/crypto/SecureRandom.js.map +1 -0
- package/dist/crypto/Signature.d.ts +448 -0
- package/dist/crypto/Signature.d.ts.map +1 -0
- package/dist/crypto/Signature.js +484 -0
- package/dist/crypto/Signature.js.map +1 -0
- package/dist/crypto/WebCrypto.d.ts +61 -0
- package/dist/crypto/WebCrypto.d.ts.map +1 -0
- package/dist/crypto/WebCrypto.js +63 -0
- package/dist/crypto/WebCrypto.js.map +1 -0
- package/dist/crypto/index.d.ts +65 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +66 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/internal/asymmetric.d.ts +2 -0
- package/dist/crypto/internal/asymmetric.d.ts.map +1 -0
- package/dist/crypto/internal/asymmetric.js +210 -0
- package/dist/crypto/internal/asymmetric.js.map +1 -0
- package/dist/crypto/internal/chacha.d.ts +46 -0
- package/dist/crypto/internal/chacha.d.ts.map +1 -0
- package/dist/crypto/internal/chacha.js +885 -0
- package/dist/crypto/internal/chacha.js.map +1 -0
- package/dist/crypto/internal/der.d.ts +6 -0
- package/dist/crypto/internal/der.d.ts.map +1 -0
- package/dist/crypto/internal/der.js +86 -0
- package/dist/crypto/internal/der.js.map +1 -0
- package/dist/crypto/internal/digest.d.ts +2 -0
- package/dist/crypto/internal/digest.d.ts.map +1 -0
- package/dist/crypto/internal/digest.js +15 -0
- package/dist/crypto/internal/digest.js.map +1 -0
- package/dist/crypto/internal/key.d.ts +2 -0
- package/dist/crypto/internal/key.d.ts.map +1 -0
- package/dist/crypto/internal/key.js +170 -0
- package/dist/crypto/internal/key.js.map +1 -0
- package/dist/crypto/internal/md5.d.ts +39 -0
- package/dist/crypto/internal/md5.d.ts.map +1 -0
- package/dist/crypto/internal/md5.js +179 -0
- package/dist/crypto/internal/md5.js.map +1 -0
- package/dist/crypto/internal/webCrypto.d.ts +2 -0
- package/dist/crypto/internal/webCrypto.d.ts.map +1 -0
- package/dist/crypto/internal/webCrypto.js +111 -0
- package/dist/crypto/internal/webCrypto.js.map +1 -0
- package/dist/devtools/DevToolsClient.d.ts.map +1 -1
- package/dist/devtools/DevToolsClient.js +2 -0
- package/dist/devtools/DevToolsClient.js.map +1 -1
- package/dist/encoding/Base64.js +36 -0
- package/dist/encoding/Base64.js.map +1 -1
- package/dist/encoding/Base64Url.d.ts.map +1 -1
- package/dist/encoding/Base64Url.js +3 -2
- package/dist/encoding/Base64Url.js.map +1 -1
- package/dist/encoding/Csv.d.ts +608 -0
- package/dist/encoding/Csv.d.ts.map +1 -0
- package/dist/encoding/Csv.js +718 -0
- package/dist/encoding/Csv.js.map +1 -0
- package/dist/encoding/Hex.d.ts +3 -2
- package/dist/encoding/Hex.d.ts.map +1 -1
- package/dist/encoding/Hex.js +3 -2
- package/dist/encoding/Hex.js.map +1 -1
- package/dist/encoding/SchemaBinary.d.ts.map +1 -1
- package/dist/encoding/SchemaBinary.js +42 -4
- package/dist/encoding/SchemaBinary.js.map +1 -1
- package/dist/encoding/Sse.d.ts.map +1 -1
- package/dist/encoding/Sse.js +3 -3
- package/dist/encoding/Sse.js.map +1 -1
- package/dist/encoding/Toml.d.ts +17 -3
- package/dist/encoding/Toml.d.ts.map +1 -1
- package/dist/encoding/Toml.js +124 -31
- package/dist/encoding/Toml.js.map +1 -1
- package/dist/encoding/Yaml.d.ts +8 -1
- package/dist/encoding/Yaml.d.ts.map +1 -1
- package/dist/encoding/Yaml.js +54 -18
- package/dist/encoding/Yaml.js.map +1 -1
- package/dist/encoding/index.d.ts +5 -0
- package/dist/encoding/index.d.ts.map +1 -1
- package/dist/encoding/index.js +5 -0
- package/dist/encoding/index.js.map +1 -1
- package/dist/eventlog/EventJournal.d.ts.map +1 -1
- package/dist/eventlog/EventJournal.js +6 -3
- package/dist/eventlog/EventJournal.js.map +1 -1
- package/dist/eventlog/EventLog.d.ts +119 -4
- package/dist/eventlog/EventLog.d.ts.map +1 -1
- package/dist/eventlog/EventLog.js +200 -12
- package/dist/eventlog/EventLog.js.map +1 -1
- package/dist/eventlog/EventLogEncryption.d.ts +41 -4
- package/dist/eventlog/EventLogEncryption.d.ts.map +1 -1
- package/dist/eventlog/EventLogEncryption.js +83 -64
- package/dist/eventlog/EventLogEncryption.js.map +1 -1
- package/dist/eventlog/EventLogMessage.d.ts +279 -0
- package/dist/eventlog/EventLogMessage.d.ts.map +1 -1
- package/dist/eventlog/EventLogMessage.js +217 -1
- package/dist/eventlog/EventLogMessage.js.map +1 -1
- package/dist/eventlog/EventLogRemote.d.ts +200 -28
- package/dist/eventlog/EventLogRemote.d.ts.map +1 -1
- package/dist/eventlog/EventLogRemote.js +186 -16
- package/dist/eventlog/EventLogRemote.js.map +1 -1
- package/dist/eventlog/EventLogServer.d.ts +3 -0
- package/dist/eventlog/EventLogServer.d.ts.map +1 -1
- package/dist/eventlog/EventLogServer.js +18 -10
- package/dist/eventlog/EventLogServer.js.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.d.ts +326 -5
- package/dist/eventlog/EventLogServerEncrypted.d.ts.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.js +769 -14
- package/dist/eventlog/EventLogServerEncrypted.js.map +1 -1
- package/dist/eventlog/EventLogSessionAuth.d.ts +5 -3
- package/dist/eventlog/EventLogSessionAuth.d.ts.map +1 -1
- package/dist/eventlog/EventLogSessionAuth.js +41 -64
- package/dist/eventlog/EventLogSessionAuth.js.map +1 -1
- package/dist/eventlog/EventRow.d.ts +4 -0
- package/dist/eventlog/EventRow.d.ts.map +1 -1
- package/dist/eventlog/EventRow.js +12 -2
- package/dist/eventlog/EventRow.js.map +1 -1
- package/dist/eventlog/SqlEventJournal.d.ts.map +1 -1
- package/dist/eventlog/SqlEventJournal.js +47 -27
- package/dist/eventlog/SqlEventJournal.js.map +1 -1
- package/dist/eventlog/SqlEventLogServerEncrypted.d.ts +21 -5
- package/dist/eventlog/SqlEventLogServerEncrypted.d.ts.map +1 -1
- package/dist/eventlog/SqlEventLogServerEncrypted.js +1048 -113
- package/dist/eventlog/SqlEventLogServerEncrypted.js.map +1 -1
- package/dist/eventlog/SqlEventLogServerUnencrypted.js +2 -2
- package/dist/eventlog/SqlEventLogServerUnencrypted.js.map +1 -1
- package/dist/eventlog/internal/batches.d.ts +12 -0
- package/dist/eventlog/internal/batches.d.ts.map +1 -0
- package/dist/eventlog/internal/batches.js +26 -0
- package/dist/eventlog/internal/batches.js.map +1 -0
- package/dist/eventlog/internal/compaction.d.ts +38 -0
- package/dist/eventlog/internal/compaction.d.ts.map +1 -0
- package/dist/eventlog/internal/compaction.js +33 -0
- package/dist/eventlog/internal/compaction.js.map +1 -0
- package/dist/eventlog/internal/conflicts.d.ts +0 -1
- package/dist/eventlog/internal/conflicts.d.ts.map +1 -1
- package/dist/eventlog/internal/conflicts.js +0 -3
- package/dist/eventlog/internal/conflicts.js.map +1 -1
- package/dist/eventlog/internal/identityRootSecretDerivation.js +66 -67
- package/dist/eventlog/internal/identityRootSecretDerivation.js.map +1 -1
- package/dist/eventlog/internal/remoteCompaction.d.ts +31 -0
- package/dist/eventlog/internal/remoteCompaction.d.ts.map +1 -0
- package/dist/eventlog/internal/remoteCompaction.js +76 -0
- package/dist/eventlog/internal/remoteCompaction.js.map +1 -0
- package/dist/http/Cookies.d.ts +172 -0
- package/dist/http/Cookies.d.ts.map +1 -1
- package/dist/http/Cookies.js +153 -10
- package/dist/http/Cookies.js.map +1 -1
- package/dist/http/FetchHttpClient.d.ts +26 -2
- package/dist/http/FetchHttpClient.d.ts.map +1 -1
- package/dist/http/FetchHttpClient.js +78 -15
- package/dist/http/FetchHttpClient.js.map +1 -1
- package/dist/http/HttpClient.d.ts +502 -8
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +296 -12
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpClientError.d.ts +8 -1
- package/dist/http/HttpClientError.d.ts.map +1 -1
- package/dist/http/HttpClientError.js +37 -1
- package/dist/http/HttpClientError.js.map +1 -1
- package/dist/http/HttpClientRequest.d.ts +9 -5
- package/dist/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/http/HttpClientRequest.js +3 -4
- package/dist/http/HttpClientRequest.js.map +1 -1
- package/dist/http/HttpClientResponse.d.ts.map +1 -1
- package/dist/http/HttpClientResponse.js +3 -2
- package/dist/http/HttpClientResponse.js.map +1 -1
- package/dist/http/HttpMethod.d.ts +7 -1
- package/dist/http/HttpMethod.d.ts.map +1 -1
- package/dist/http/HttpMethod.js +3 -8
- package/dist/http/HttpMethod.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts +1 -1
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +14 -16
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpRouter.d.ts.map +1 -1
- package/dist/http/HttpRouter.js +2 -1
- package/dist/http/HttpRouter.js.map +1 -1
- package/dist/http/HttpServerError.js +2 -2
- package/dist/http/HttpServerError.js.map +1 -1
- package/dist/http/HttpServerRequest.d.ts +11 -3
- package/dist/http/HttpServerRequest.d.ts.map +1 -1
- package/dist/http/HttpServerRequest.js +77 -25
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/http/HttpServerResponse.js +3 -2
- package/dist/http/HttpServerResponse.js.map +1 -1
- package/dist/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/http/HttpStaticServer.js +48 -21
- package/dist/http/HttpStaticServer.js.map +1 -1
- package/dist/http/HttpTraceContext.d.ts +2 -1
- package/dist/http/HttpTraceContext.d.ts.map +1 -1
- package/dist/http/HttpTraceContext.js +7 -5
- package/dist/http/HttpTraceContext.js.map +1 -1
- package/dist/http/MultipartParser/internal/contentType.js +3 -3
- package/dist/http/ProblemDetails.d.ts +96 -0
- package/dist/http/ProblemDetails.d.ts.map +1 -0
- package/dist/http/ProblemDetails.js +98 -0
- package/dist/http/ProblemDetails.js.map +1 -0
- package/dist/http/UrlParams.d.ts +3 -1
- package/dist/http/UrlParams.d.ts.map +1 -1
- package/dist/http/UrlParams.js +4 -2
- package/dist/http/UrlParams.js.map +1 -1
- package/dist/http/index.d.ts +5 -0
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +5 -0
- package/dist/http/index.js.map +1 -1
- package/dist/http/internal/compression.js +4 -5
- package/dist/http/internal/compression.js.map +1 -1
- package/dist/http/internal/decompression.js +6 -2
- package/dist/http/internal/decompression.js.map +1 -1
- package/dist/http/internal/httpBody.js +8 -1
- package/dist/http/internal/httpBody.js.map +1 -1
- package/dist/http/internal/urlParams.js +33 -0
- package/dist/http/internal/urlParams.js.map +1 -1
- package/dist/http-api/HttpApi.d.ts +3 -6
- package/dist/http-api/HttpApi.d.ts.map +1 -1
- package/dist/http-api/HttpApi.js +3 -6
- 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 +43 -13
- package/dist/http-api/HttpApiBuilder.js.map +1 -1
- package/dist/http-api/HttpApiClient.d.ts +140 -7
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +193 -44
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/http-api/HttpApiEndpoint.d.ts +24 -7
- package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/http-api/HttpApiEndpoint.js +123 -32
- package/dist/http-api/HttpApiEndpoint.js.map +1 -1
- package/dist/http-api/HttpApiError.d.ts +185 -13
- package/dist/http-api/HttpApiError.d.ts.map +1 -1
- package/dist/http-api/HttpApiError.js +128 -0
- package/dist/http-api/HttpApiError.js.map +1 -1
- package/dist/http-api/HttpApiMiddleware.d.ts +64 -17
- package/dist/http-api/HttpApiMiddleware.d.ts.map +1 -1
- package/dist/http-api/HttpApiMiddleware.js +85 -1
- package/dist/http-api/HttpApiMiddleware.js.map +1 -1
- package/dist/http-api/HttpApiSchema.d.ts +142 -33
- package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
- package/dist/http-api/HttpApiSchema.js +123 -59
- package/dist/http-api/HttpApiSchema.js.map +1 -1
- package/dist/http-api/HttpApiTest.d.ts.map +1 -1
- package/dist/http-api/HttpApiTest.js +3 -2
- package/dist/http-api/HttpApiTest.js.map +1 -1
- package/dist/http-api/OpenApi.d.ts.map +1 -1
- package/dist/http-api/OpenApi.js +25 -16
- package/dist/http-api/OpenApi.js.map +1 -1
- package/dist/http-api/internal/toCodecHttpProperties.d.ts +2 -0
- package/dist/http-api/internal/toCodecHttpProperties.d.ts.map +1 -0
- package/dist/http-api/internal/toCodecHttpProperties.js +38 -0
- package/dist/http-api/internal/toCodecHttpProperties.js.map +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/internal/arbitrary/runner.d.ts.map +1 -1
- package/dist/internal/arbitrary/runner.js +120 -44
- package/dist/internal/arbitrary/runner.js.map +1 -1
- package/dist/internal/core.js +2 -0
- package/dist/internal/core.js.map +1 -1
- package/dist/internal/effect.js +46 -27
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/equal.js +14 -0
- package/dist/internal/equal.js.map +1 -1
- package/dist/internal/glob.d.ts +2 -0
- package/dist/internal/glob.d.ts.map +1 -0
- package/dist/internal/glob.js +630 -0
- package/dist/internal/glob.js.map +1 -0
- package/dist/internal/jsonSchema.d.ts +2 -0
- package/dist/internal/jsonSchema.d.ts.map +1 -0
- package/dist/internal/jsonSchema.js +28 -0
- package/dist/internal/jsonSchema.js.map +1 -0
- package/dist/internal/matcher.js +11 -1
- package/dist/internal/matcher.js.map +1 -1
- package/dist/internal/persistence.js +9 -0
- package/dist/internal/persistence.js.map +1 -1
- package/dist/internal/rcRef.js +4 -1
- package/dist/internal/rcRef.js.map +1 -1
- package/dist/internal/schema/compilerRegistry.js +4 -1
- package/dist/internal/schema/compilerRegistry.js.map +1 -1
- package/dist/internal/schema/content.d.ts +2 -0
- package/dist/internal/schema/content.d.ts.map +1 -0
- package/dist/internal/schema/content.js +13 -0
- package/dist/internal/schema/content.js.map +1 -0
- package/dist/internal/schema/fromJsonSchemaDocument.js +173 -185
- package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
- package/dist/internal/schema/fromRepresentation.js +2 -1
- package/dist/internal/schema/fromRepresentation.js.map +1 -1
- package/dist/internal/schema/standardSchema.js +8 -2
- package/dist/internal/schema/standardSchema.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +9 -6
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/schema/toCodec.js +21 -24
- package/dist/internal/schema/toCodec.js.map +1 -1
- package/dist/internal/schema/toJsonSchemaDocument.js +205 -140
- package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
- package/dist/internal/schema/toRepresentation.js +107 -129
- package/dist/internal/schema/toRepresentation.js.map +1 -1
- package/dist/internal/sql.d.ts +2 -0
- package/dist/internal/sql.d.ts.map +1 -0
- package/dist/internal/sql.js +13 -0
- package/dist/internal/sql.js.map +1 -0
- package/dist/internal/trie.js +42 -13
- package/dist/internal/trie.js.map +1 -1
- package/dist/internal/ulid.js +41 -0
- package/dist/internal/ulid.js.map +1 -1
- package/dist/internal/uuid.js +52 -8
- package/dist/internal/uuid.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/observability/Otlp.d.ts +15 -4
- package/dist/observability/Otlp.d.ts.map +1 -1
- package/dist/observability/Otlp.js +10 -0
- package/dist/observability/Otlp.js.map +1 -1
- package/dist/observability/OtlpProxy.d.ts +154 -0
- package/dist/observability/OtlpProxy.d.ts.map +1 -0
- package/dist/observability/OtlpProxy.js +235 -0
- package/dist/observability/OtlpProxy.js.map +1 -0
- package/dist/observability/OtlpResource.d.ts +7 -0
- package/dist/observability/OtlpResource.d.ts.map +1 -1
- package/dist/observability/OtlpResource.js +11 -1
- package/dist/observability/OtlpResource.js.map +1 -1
- package/dist/observability/OtlpTracer.d.ts.map +1 -1
- package/dist/observability/OtlpTracer.js +4 -0
- package/dist/observability/OtlpTracer.js.map +1 -1
- package/dist/observability/index.d.ts +5 -0
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +5 -0
- package/dist/observability/index.js.map +1 -1
- package/dist/persistence/CircuitBreaker.d.ts +897 -0
- package/dist/persistence/CircuitBreaker.d.ts.map +1 -0
- package/dist/persistence/CircuitBreaker.js +1165 -0
- package/dist/persistence/CircuitBreaker.js.map +1 -0
- package/dist/persistence/KeyValueStore.d.ts +47 -2
- package/dist/persistence/KeyValueStore.d.ts.map +1 -1
- package/dist/persistence/KeyValueStore.js +129 -18
- package/dist/persistence/KeyValueStore.js.map +1 -1
- package/dist/persistence/PersistedQueue.d.ts +9 -0
- package/dist/persistence/PersistedQueue.d.ts.map +1 -1
- package/dist/persistence/PersistedQueue.js +94 -52
- package/dist/persistence/PersistedQueue.js.map +1 -1
- package/dist/persistence/Persistence.d.ts +10 -4
- package/dist/persistence/Persistence.d.ts.map +1 -1
- package/dist/persistence/Persistence.js +18 -11
- package/dist/persistence/Persistence.js.map +1 -1
- package/dist/persistence/Redis.d.ts +78 -2
- package/dist/persistence/Redis.d.ts.map +1 -1
- package/dist/persistence/Redis.js +62 -7
- package/dist/persistence/Redis.js.map +1 -1
- 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 +237 -71
- package/dist/process/ChildProcess.d.ts.map +1 -1
- package/dist/process/ChildProcess.js +56 -158
- package/dist/process/ChildProcess.js.map +1 -1
- package/dist/process/ChildProcessSpawner.d.ts +35 -0
- package/dist/process/ChildProcessSpawner.d.ts.map +1 -1
- package/dist/process/ChildProcessSpawner.js +5 -2
- package/dist/process/ChildProcessSpawner.js.map +1 -1
- package/dist/process/CommandLine.d.ts +294 -0
- package/dist/process/CommandLine.d.ts.map +1 -0
- package/dist/process/CommandLine.js +481 -0
- package/dist/process/CommandLine.js.map +1 -0
- package/dist/process/index.d.ts +5 -0
- package/dist/process/index.d.ts.map +1 -1
- package/dist/process/index.js +5 -0
- package/dist/process/index.js.map +1 -1
- package/dist/reactivity/AsyncResult.d.ts +1 -1
- package/dist/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/reactivity/Atom.d.ts +2 -1
- package/dist/reactivity/Atom.d.ts.map +1 -1
- package/dist/reactivity/Atom.js +3 -4
- package/dist/reactivity/Atom.js.map +1 -1
- package/dist/reactivity/AtomRegistry.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts +16 -1
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +59 -24
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcMessage.d.ts +10 -1
- package/dist/rpc/RpcMessage.d.ts.map +1 -1
- package/dist/rpc/RpcMessage.js +1 -0
- package/dist/rpc/RpcMessage.js.map +1 -1
- package/dist/rpc/RpcSerialization.d.ts +14 -0
- package/dist/rpc/RpcSerialization.d.ts.map +1 -1
- package/dist/rpc/RpcSerialization.js +26 -8
- package/dist/rpc/RpcSerialization.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts +31 -0
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +139 -56
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/rpc/RpcTest.d.ts +1 -0
- package/dist/rpc/RpcTest.d.ts.map +1 -1
- package/dist/rpc/RpcTest.js +1 -0
- package/dist/rpc/RpcTest.js.map +1 -1
- package/dist/schema/Model.d.ts +14 -0
- package/dist/schema/Model.d.ts.map +1 -1
- package/dist/schema/Model.js +18 -3
- package/dist/schema/Model.js.map +1 -1
- package/dist/sql/Migrator.d.ts +2 -20
- package/dist/sql/Migrator.d.ts.map +1 -1
- package/dist/sql/Migrator.js +13 -55
- package/dist/sql/Migrator.js.map +1 -1
- package/dist/sql/MigratorFileSystem.d.ts +21 -0
- package/dist/sql/MigratorFileSystem.d.ts.map +1 -0
- package/dist/sql/MigratorFileSystem.js +57 -0
- package/dist/sql/MigratorFileSystem.js.map +1 -0
- package/dist/sql/SqlClient.d.ts +9 -4
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +13 -10
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/sql/SqlResolver.d.ts +4 -0
- package/dist/sql/SqlResolver.d.ts.map +1 -1
- package/dist/sql/SqlResolver.js +18 -4
- package/dist/sql/SqlResolver.js.map +1 -1
- package/dist/sql/Statement.d.ts +27 -6
- package/dist/sql/Statement.d.ts.map +1 -1
- package/dist/sql/Statement.js +21 -15
- package/dist/sql/Statement.js.map +1 -1
- package/dist/sql/index.js +1 -1
- package/dist/testing/index.d.ts +0 -5
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +0 -5
- package/dist/testing/index.js.map +1 -1
- package/dist/workflow/DurableDeferred.d.ts.map +1 -1
- package/dist/workflow/DurableDeferred.js +21 -2
- package/dist/workflow/DurableDeferred.js.map +1 -1
- package/dist/workflow/internal/crypto.js +9 -8
- package/dist/workflow/internal/crypto.js.map +1 -1
- package/package.json +3 -1
- package/src/Arbitrary.ts +10 -2
- package/src/BigDecimal.ts +3 -0
- package/src/Channel.ts +64 -29
- package/src/Config.ts +7 -1
- package/src/Context.ts +34 -10
- package/src/Cron.ts +178 -29
- package/src/Data.ts +60 -265
- package/src/Duration.ts +140 -0
- package/src/Effect.ts +915 -86
- package/src/Equal.ts +8 -1
- package/src/Exit.ts +3 -3
- package/src/FileSystem.ts +65 -4
- package/src/Formatter.ts +28 -13
- package/src/Glob.ts +205 -0
- package/src/Hash.ts +4 -1
- package/src/JsonPatch.ts +4 -0
- package/src/JsonSchema.ts +12 -40
- package/src/Match.ts +127 -0
- package/src/Metric.ts +3 -3
- package/src/MutableList.ts +7 -5
- package/src/MutableRef.ts +8 -1
- package/src/PartitionedSemaphore.ts +24 -13
- package/src/Pool.ts +182 -52
- package/src/PubSub.ts +5 -6
- package/src/Random.ts +3 -3
- package/src/RcMap.ts +5 -1
- package/src/Ref.ts +8 -0
- package/src/Schedule.ts +27 -4
- package/src/Schema.ts +1237 -87
- package/src/SchemaAST.ts +20 -20
- package/src/SchemaGetter.ts +27 -11
- package/src/SchemaParser.ts +51 -18
- package/src/SchemaRepresentation.ts +50 -34
- package/src/SchemaTransformation.ts +17 -5
- package/src/ScopedCache.ts +5 -9
- package/src/Semaphore.ts +208 -40
- package/src/Sink.ts +15 -2
- package/src/Stream.ts +48 -22
- package/src/String.ts +3 -0
- package/src/Terminal.ts +19 -1
- package/src/Tracer.ts +15 -1
- package/src/ai/AiError.ts +56 -80
- package/src/ai/Decision.ts +257 -6
- package/src/ai/DecisionModel.ts +171 -28
- package/src/ai/LanguageModel.ts +9 -0
- package/src/ai/McpServer.ts +1283 -299
- package/src/ai/McpTest.ts +380 -0
- package/src/ai/Prompt.ts +65 -0
- package/src/ai/Response.ts +36 -31
- package/src/ai/Tool.ts +65 -10
- package/src/ai/Toolkit.ts +4 -1
- package/src/ai/index.ts +6 -0
- package/src/ai/internal/mcpCore.ts +78 -44
- package/src/ai/internal/mcpProtocol/v2024_11_05.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2025_03_26.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2025_06_18.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2025_11_25.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2026_07_28.ts +15 -10
- package/src/ai/internal/mcpProtocol.ts +29 -0
- package/src/ai/internal/mcpRuntime.ts +9 -5
- package/src/ai/internal/mcpStatefulRuntime.ts +14 -2
- package/src/cli/Argument.ts +21 -0
- package/src/cli/CliError.ts +90 -3
- package/src/cli/CliOutput.ts +300 -55
- package/src/cli/Command.ts +76 -41
- package/src/cli/Completions.ts +51 -0
- package/src/cli/Flag.ts +122 -0
- package/src/cli/GlobalFlag.ts +6 -7
- package/src/cli/HelpDoc.ts +18 -1
- package/src/cli/Param.ts +35 -6
- package/src/cli/Primitive.ts +16 -1
- package/src/cli/Prompt.ts +1 -0
- package/src/cli/TerminalCapabilities.ts +6 -3
- package/src/cli/internal/completions/bash.ts +79 -29
- package/src/cli/internal/help.ts +21 -9
- package/src/cluster/ClusterWorkflowEngine.ts +46 -16
- package/src/cluster/MessageStorage.ts +19 -14
- package/src/cluster/Sharding.ts +176 -47
- package/src/cluster/ShardingConfig.ts +43 -0
- package/src/cluster/SingleRunner.ts +3 -3
- package/src/cluster/Snowflake.ts +3 -7
- package/src/cluster/SqlMessageStorage.ts +49 -17
- package/src/cluster/SqlRunnerStorage.ts +143 -70
- package/src/cluster/internal/entityManager.ts +75 -22
- package/src/crypto/Aead.ts +517 -0
- package/src/crypto/Cipher.ts +326 -0
- package/src/crypto/CryptoError.ts +242 -0
- package/src/crypto/Digest.ts +167 -0
- package/src/crypto/Kdf.ts +315 -0
- package/src/crypto/KeyAgreement.ts +489 -0
- package/src/crypto/KeyFormat.ts +712 -0
- package/src/crypto/KeyWrap.ts +639 -0
- package/src/crypto/Mac.ts +386 -0
- package/src/crypto/SecureRandom.ts +459 -0
- package/src/crypto/Signature.ts +673 -0
- package/src/crypto/WebCrypto.ts +64 -0
- package/src/crypto/index.ts +78 -0
- package/src/crypto/internal/asymmetric.ts +329 -0
- package/src/crypto/internal/chacha.ts +1088 -0
- package/src/crypto/internal/der.ts +110 -0
- package/src/crypto/internal/digest.ts +16 -0
- package/src/crypto/internal/key.ts +235 -0
- package/src/crypto/internal/md5.ts +170 -0
- package/src/crypto/internal/webCrypto.ts +150 -0
- package/src/devtools/DevToolsClient.ts +2 -0
- package/src/encoding/Base64.ts +38 -0
- package/src/encoding/Base64Url.ts +5 -2
- package/src/encoding/Csv.ts +1298 -0
- package/src/encoding/Hex.ts +3 -2
- package/src/encoding/SchemaBinary.ts +40 -4
- package/src/encoding/Sse.ts +4 -3
- package/src/encoding/Toml.ts +117 -35
- package/src/encoding/Yaml.ts +61 -18
- package/src/encoding/index.ts +6 -0
- package/src/eventlog/EventJournal.ts +4 -3
- package/src/eventlog/EventLog.ts +340 -15
- package/src/eventlog/EventLogEncryption.ts +118 -110
- package/src/eventlog/EventLogMessage.ts +273 -1
- package/src/eventlog/EventLogRemote.ts +367 -23
- package/src/eventlog/EventLogServer.ts +23 -8
- package/src/eventlog/EventLogServerEncrypted.ts +1130 -67
- package/src/eventlog/EventLogSessionAuth.ts +56 -70
- package/src/eventlog/EventRow.ts +12 -3
- package/src/eventlog/SqlEventJournal.ts +68 -45
- package/src/eventlog/SqlEventLogServerEncrypted.ts +1244 -136
- package/src/eventlog/SqlEventLogServerUnencrypted.ts +2 -2
- package/src/eventlog/internal/batches.ts +30 -0
- package/src/eventlog/internal/compaction.ts +64 -0
- package/src/eventlog/internal/conflicts.ts +0 -4
- package/src/eventlog/internal/identityRootSecretDerivation.ts +93 -123
- package/src/eventlog/internal/remoteCompaction.ts +92 -0
- package/src/http/Cookies.ts +291 -12
- package/src/http/FetchHttpClient.ts +88 -16
- package/src/http/HttpClient.ts +636 -29
- package/src/http/HttpClientError.ts +35 -1
- package/src/http/HttpClientRequest.ts +21 -10
- package/src/http/HttpClientResponse.ts +3 -2
- package/src/http/HttpMethod.ts +10 -2
- package/src/http/HttpMiddleware.ts +15 -18
- package/src/http/HttpRouter.ts +2 -1
- package/src/http/HttpServerError.ts +2 -2
- package/src/http/HttpServerRequest.ts +101 -30
- package/src/http/HttpServerResponse.ts +3 -2
- package/src/http/HttpStaticServer.ts +51 -22
- package/src/http/HttpTraceContext.ts +7 -4
- package/src/http/MultipartParser/internal/contentType.ts +3 -3
- package/src/http/ProblemDetails.ts +149 -0
- package/src/http/UrlParams.ts +6 -1
- package/src/http/index.ts +6 -0
- package/src/http/internal/compression.ts +4 -5
- package/src/http/internal/decompression.ts +10 -4
- package/src/http/internal/httpBody.ts +10 -2
- package/src/http/internal/urlParams.ts +37 -0
- package/src/http-api/HttpApi.ts +3 -6
- package/src/http-api/HttpApiBuilder.ts +61 -19
- package/src/http-api/HttpApiClient.ts +284 -72
- package/src/http-api/HttpApiEndpoint.ts +135 -35
- package/src/http-api/HttpApiError.ts +250 -0
- package/src/http-api/HttpApiMiddleware.ts +95 -1
- package/src/http-api/HttpApiSchema.ts +236 -52
- package/src/http-api/HttpApiTest.ts +3 -2
- package/src/http-api/OpenApi.ts +20 -17
- package/src/http-api/internal/toCodecHttpProperties.ts +56 -0
- package/src/index.ts +6 -6
- package/src/internal/arbitrary/runner.ts +133 -36
- package/src/internal/core.ts +2 -0
- package/src/internal/effect.ts +58 -34
- package/src/internal/equal.ts +17 -0
- package/src/internal/glob.ts +736 -0
- package/src/internal/jsonSchema.ts +27 -0
- package/src/internal/matcher.ts +18 -1
- package/src/internal/persistence.ts +11 -0
- package/src/internal/rcRef.ts +4 -1
- package/src/internal/schema/compilerRegistry.ts +6 -1
- package/src/internal/schema/content.ts +18 -0
- package/src/internal/schema/fromJsonSchemaDocument.ts +228 -190
- package/src/internal/schema/fromRepresentation.ts +2 -1
- package/src/internal/schema/standardSchema.ts +2 -2
- package/src/internal/schema/toCodeDocument.ts +11 -7
- package/src/internal/schema/toCodec.ts +26 -22
- package/src/internal/schema/toJsonSchemaDocument.ts +189 -167
- package/src/internal/schema/toRepresentation.ts +122 -140
- package/src/internal/sql.ts +14 -0
- package/src/internal/trie.ts +43 -14
- package/src/internal/ulid.ts +44 -0
- package/src/internal/uuid.ts +57 -16
- package/src/internal/version.ts +1 -1
- package/src/observability/Otlp.ts +21 -4
- package/src/observability/OtlpProxy.ts +314 -0
- package/src/observability/OtlpResource.ts +9 -1
- package/src/observability/OtlpTracer.ts +4 -0
- package/src/observability/index.ts +6 -0
- package/src/persistence/CircuitBreaker.ts +1678 -0
- package/src/persistence/KeyValueStore.ts +219 -22
- package/src/persistence/PersistedQueue.ts +128 -59
- package/src/persistence/Persistence.ts +20 -13
- package/src/persistence/Redis.ts +129 -8
- package/src/persistence/index.ts +6 -0
- package/src/process/ChildProcess.ts +285 -264
- package/src/process/ChildProcessSpawner.ts +46 -2
- package/src/process/CommandLine.ts +630 -0
- package/src/process/index.ts +6 -0
- package/src/reactivity/AsyncResult.ts +1 -1
- package/src/reactivity/Atom.ts +5 -5
- package/src/reactivity/AtomRegistry.ts +1 -1
- package/src/rpc/RpcClient.ts +75 -36
- package/src/rpc/RpcMessage.ts +10 -1
- package/src/rpc/RpcSerialization.ts +35 -9
- package/src/rpc/RpcServer.ts +176 -63
- package/src/rpc/RpcTest.ts +3 -0
- package/src/schema/Model.ts +26 -3
- package/src/sql/Migrator.ts +15 -69
- package/src/sql/MigratorFileSystem.ts +71 -0
- package/src/sql/SqlClient.ts +13 -20
- package/src/sql/SqlResolver.ts +23 -9
- package/src/sql/Statement.ts +38 -9
- package/src/sql/index.ts +1 -1
- package/src/testing/index.ts +0 -6
- package/src/workflow/DurableDeferred.ts +23 -6
- package/src/workflow/internal/crypto.ts +15 -11
- package/dist/Crypto.d.ts +0 -244
- package/dist/Crypto.d.ts.map +0 -1
- package/dist/Crypto.js +0 -139
- package/dist/Crypto.js.map +0 -1
- package/dist/testing/TestCrypto.d.ts +0 -73
- package/dist/testing/TestCrypto.d.ts.map +0 -1
- package/dist/testing/TestCrypto.js +0 -87
- package/dist/testing/TestCrypto.js.map +0 -1
- package/src/Crypto.ts +0 -347
- package/src/testing/TestCrypto.ts +0 -94
package/src/ai/McpServer.ts
CHANGED
|
@@ -16,6 +16,7 @@ import * as Cause from "../Cause.ts"
|
|
|
16
16
|
import * as Context from "../Context.ts"
|
|
17
17
|
import * as Data from "../Data.ts"
|
|
18
18
|
import * as Deferred from "../Deferred.ts"
|
|
19
|
+
import * as Duration from "../Duration.ts"
|
|
19
20
|
import * as Effect from "../Effect.ts"
|
|
20
21
|
import * as ErrorReporter from "../ErrorReporter.ts"
|
|
21
22
|
import * as Exit from "../Exit.ts"
|
|
@@ -46,6 +47,8 @@ import * as SchemaAST from "../SchemaAST.ts"
|
|
|
46
47
|
import * as Scope from "../Scope.ts"
|
|
47
48
|
import type { Stdio } from "../Stdio.ts"
|
|
48
49
|
import * as Stream from "../Stream.ts"
|
|
50
|
+
import * as Tracer from "../Tracer.ts"
|
|
51
|
+
import type * as Types from "../Types.ts"
|
|
49
52
|
import * as AiError from "./AiError.ts"
|
|
50
53
|
import * as McpCore from "./internal/mcpCore.ts"
|
|
51
54
|
import * as McpProtocolInternal from "./internal/mcpProtocol.ts"
|
|
@@ -105,6 +108,7 @@ const internalState = new WeakMap<object, {
|
|
|
105
108
|
readonly core: McpCore.McpCore
|
|
106
109
|
readonly notifications: Queue.Dequeue<QueuedServerNotification>
|
|
107
110
|
readonly notificationDelivery: { consumers: number; listChangeRevision: number; requestEndpoints: number }
|
|
111
|
+
readonly globalMiddleware: Array<middleware.Fn<any, any, any>>
|
|
108
112
|
}>()
|
|
109
113
|
|
|
110
114
|
// Request-scoped HTTP servers deliver a request's own notifications through
|
|
@@ -166,13 +170,29 @@ const toInternalServerNotification = (
|
|
|
166
170
|
}
|
|
167
171
|
}
|
|
168
172
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
const middlewareKeyPrefix = "effect/ai/McpServer/Middleware-"
|
|
174
|
+
|
|
175
|
+
// Do not capture request services or middleware stacks at registration.
|
|
176
|
+
const requestServiceKeys = new Set<string>([
|
|
177
|
+
McpRequestContext.key,
|
|
178
|
+
McpServerClient.key,
|
|
179
|
+
HttpServerRequest.HttpServerRequest.key,
|
|
180
|
+
HttpServerRequest.ParsedSearchParams.key,
|
|
181
|
+
HttpRouter.RouteContext.key,
|
|
182
|
+
CurrentLogLevel.key,
|
|
183
|
+
Scope.Scope.key,
|
|
184
|
+
Tracer.ParentSpan.key
|
|
185
|
+
])
|
|
186
|
+
|
|
187
|
+
const omitRequestServices = <Services>(context: Context.Context<Services>): Context.Context<Services> => {
|
|
188
|
+
const services = new Map<string, any>()
|
|
189
|
+
for (const [key, value] of context.mapUnsafe) {
|
|
190
|
+
if (!requestServiceKeys.has(key) && !key.startsWith(middlewareKeyPrefix)) {
|
|
191
|
+
services.set(key, value)
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return Context.makeUnsafe(services)
|
|
195
|
+
}
|
|
176
196
|
|
|
177
197
|
const provideInvocationContext = <A, E, R>(
|
|
178
198
|
effect: Effect.Effect<A, E, R>,
|
|
@@ -199,6 +219,703 @@ const provideInvocationContext = <A, E, R>(
|
|
|
199
219
|
>
|
|
200
220
|
}
|
|
201
221
|
|
|
222
|
+
// -----------------------------------------------------------------------------
|
|
223
|
+
// Request-level dependencies
|
|
224
|
+
// -----------------------------------------------------------------------------
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Marks a request-level dependency of an MCP registration or middleware.
|
|
228
|
+
*
|
|
229
|
+
* **Details**
|
|
230
|
+
*
|
|
231
|
+
* Registrations carry handler dependencies as `McpRequest<"Requires", S>`.
|
|
232
|
+
* MCP middleware and transports discharge these markers; providing `S` with
|
|
233
|
+
* `Layer.provide` or `Effect.provide` does not.
|
|
234
|
+
*
|
|
235
|
+
* `layerHttp` and `layerHttpRequestScoped` convert the markers they don't
|
|
236
|
+
* discharge into `HttpRouter.Request` markers, so `HttpRouter.middleware` can
|
|
237
|
+
* satisfy them. On stdio and custom transports an undischarged marker is a
|
|
238
|
+
* compile error.
|
|
239
|
+
*
|
|
240
|
+
* @see {@link middleware} for discharging request-level dependencies
|
|
241
|
+
*
|
|
242
|
+
* @stability unstable
|
|
243
|
+
* @category utility types
|
|
244
|
+
* @since 4.0.0
|
|
245
|
+
*/
|
|
246
|
+
export interface McpRequest<Kind extends string, T> {
|
|
247
|
+
readonly _: unique symbol
|
|
248
|
+
readonly kind: Kind
|
|
249
|
+
readonly type: T
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Helper types for `McpRequest` markers.
|
|
254
|
+
*
|
|
255
|
+
* @stability unstable
|
|
256
|
+
* @category utility types
|
|
257
|
+
* @since 4.0.0
|
|
258
|
+
*/
|
|
259
|
+
export declare namespace McpRequest {
|
|
260
|
+
/**
|
|
261
|
+
* Wraps each member of a union in an `McpRequest` marker of the supplied kind.
|
|
262
|
+
*
|
|
263
|
+
* @stability unstable
|
|
264
|
+
* @category utility types
|
|
265
|
+
* @since 4.0.0
|
|
266
|
+
*/
|
|
267
|
+
export type From<Kind extends string, R> = R extends infer T ? McpRequest<Kind, T> : never
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Extracts the services from `McpRequest` markers of the supplied kind.
|
|
271
|
+
*
|
|
272
|
+
* @stability unstable
|
|
273
|
+
* @category utility types
|
|
274
|
+
* @since 4.0.0
|
|
275
|
+
*/
|
|
276
|
+
export type Only<Kind extends string, A> = A extends McpRequest<Kind, infer T> ? T : never
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Removes `McpRequest` markers from a union.
|
|
280
|
+
*
|
|
281
|
+
* @stability unstable
|
|
282
|
+
* @category utility types
|
|
283
|
+
* @since 4.0.0
|
|
284
|
+
*/
|
|
285
|
+
export type Without<A> = A extends McpRequest<infer _Kind, infer _> ? never : A
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Opaque handler result. Middleware can wrap execution and provide services,
|
|
290
|
+
* but cannot inspect or replace the result.
|
|
291
|
+
*
|
|
292
|
+
* @stability unstable
|
|
293
|
+
* @category middleware
|
|
294
|
+
* @since 4.0.0
|
|
295
|
+
*/
|
|
296
|
+
export interface MiddlewareSuccess {
|
|
297
|
+
readonly _: unique symbol
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* The request methods that run MCP middleware. More methods may be added, so
|
|
302
|
+
* don't `switch` on it exhaustively without a default case.
|
|
303
|
+
*
|
|
304
|
+
* @stability unstable
|
|
305
|
+
* @category middleware
|
|
306
|
+
* @since 4.0.0
|
|
307
|
+
*/
|
|
308
|
+
export type MiddlewareMethod =
|
|
309
|
+
| "tools/call"
|
|
310
|
+
| "resources/read"
|
|
311
|
+
| "prompts/get"
|
|
312
|
+
| "completion/complete"
|
|
313
|
+
| "tools/list"
|
|
314
|
+
| "resources/list"
|
|
315
|
+
| "resources/templates/list"
|
|
316
|
+
| "prompts/list"
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Request metadata passed to MCP middleware.
|
|
320
|
+
*
|
|
321
|
+
* **Details**
|
|
322
|
+
*
|
|
323
|
+
* `target` is the tool name, the requested resource URI, or the prompt name.
|
|
324
|
+
* For `completion/complete` it is the prompt name, or the URI template of the
|
|
325
|
+
* resource template being completed. `payload` holds the request parameters.
|
|
326
|
+
*
|
|
327
|
+
* On list requests, middleware runs only when it wraps a {@link visibility},
|
|
328
|
+
* once for each registration it wraps. `target` is then the tool name, the
|
|
329
|
+
* resource URI, the URI template or the prompt name of that registration, and
|
|
330
|
+
* `payload` is `undefined`.
|
|
331
|
+
*
|
|
332
|
+
* `headers` are the HTTP request headers. They are empty on stdio, on custom
|
|
333
|
+
* transports and for in-process calls. `sessionId` is the `Mcp-Session-Id`
|
|
334
|
+
* header, so it is `undefined` outside sessionful HTTP.
|
|
335
|
+
*
|
|
336
|
+
* @stability unstable
|
|
337
|
+
* @category middleware
|
|
338
|
+
* @since 4.0.0
|
|
339
|
+
*/
|
|
340
|
+
export interface MiddlewareOptions {
|
|
341
|
+
readonly method: MiddlewareMethod
|
|
342
|
+
readonly target: string
|
|
343
|
+
readonly payload: unknown
|
|
344
|
+
readonly requestContext: McpRequestContext["Service"]
|
|
345
|
+
readonly headers: Headers.Headers
|
|
346
|
+
readonly sessionId: string | undefined
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const MiddlewareTypeId = "~effect/ai/McpServer/Middleware"
|
|
350
|
+
|
|
351
|
+
type MiddlewareConfig = {
|
|
352
|
+
provides: any
|
|
353
|
+
error: McpErrorBase
|
|
354
|
+
requires: any
|
|
355
|
+
layerError: any
|
|
356
|
+
layerRequires: any
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
type MiddlewareLayer<Config extends MiddlewareConfig, R> = Layer.Layer<
|
|
360
|
+
McpRequest.From<"Requires", Config["provides"]>,
|
|
361
|
+
Config["layerError"],
|
|
362
|
+
R | Config["layerRequires"] | McpRequest.From<"Requires", Config["requires"]>
|
|
363
|
+
>
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Composable MCP middleware.
|
|
367
|
+
*
|
|
368
|
+
* **Details**
|
|
369
|
+
*
|
|
370
|
+
* Provide `layer` to registration layers, or to the Effect form of a
|
|
371
|
+
* registration, to run the middleware for those registrations. Use
|
|
372
|
+
* `layerGlobal` to run it for every request on the server.
|
|
373
|
+
*
|
|
374
|
+
* Services the middleware reads per request are `McpRequest<"Requires", S>`
|
|
375
|
+
* requirements of `layer` and `layerGlobal`, like the request-level
|
|
376
|
+
* dependencies of a registration. A middleware that provides `S` meets them
|
|
377
|
+
* when it runs outside this one: `a.combine(b)` runs `b` outside `a`, and so
|
|
378
|
+
* does providing `b.layer` or `b.layerGlobal` outside `a.layer`, though
|
|
379
|
+
* `layerGlobal` installs `b` for the whole server. The transport discharges
|
|
380
|
+
* the services it supplies, and `layerHttp` turns the rest into
|
|
381
|
+
* `HttpRouter.Request` requirements that an `HttpRouter.middleware` can meet.
|
|
382
|
+
*
|
|
383
|
+
* @see {@link middleware} for creating MCP middleware
|
|
384
|
+
*
|
|
385
|
+
* @stability unstable
|
|
386
|
+
* @category middleware
|
|
387
|
+
* @since 4.0.0
|
|
388
|
+
*/
|
|
389
|
+
export interface Middleware<Config extends MiddlewareConfig> {
|
|
390
|
+
readonly [MiddlewareTypeId]: Config
|
|
391
|
+
readonly layer: MiddlewareLayer<Config, never>
|
|
392
|
+
readonly layerGlobal: MiddlewareLayer<Config, McpServer>
|
|
393
|
+
readonly combine: <Config2 extends MiddlewareConfig>(other: Middleware<Config2>) => Middleware<{
|
|
394
|
+
provides: Config2["provides"] | Config["provides"]
|
|
395
|
+
error: Config2["error"] | Config["error"]
|
|
396
|
+
requires: Exclude<Config["requires"], Config2["provides"]> | Config2["requires"]
|
|
397
|
+
layerError: Config["layerError"] | Config2["layerError"]
|
|
398
|
+
layerRequires: Config["layerRequires"] | Config2["layerRequires"]
|
|
399
|
+
}>
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Creates MCP middleware that runs around `tools/call`, `resources/read`,
|
|
404
|
+
* `prompts/get` and `completion/complete` requests.
|
|
405
|
+
*
|
|
406
|
+
* **Details**
|
|
407
|
+
*
|
|
408
|
+
* Middleware is how request-level dependencies are satisfied: declare the
|
|
409
|
+
* services it provides with `middleware<{ provides: S }>()` and provide them to
|
|
410
|
+
* the handler effect. It receives the request headers, session id and request
|
|
411
|
+
* context, so it can resolve the current user per request.
|
|
412
|
+
*
|
|
413
|
+
* Pass a function, or an Effect that builds the function. Services the Effect
|
|
414
|
+
* reads are requirements of the middleware layer. Services the function reads
|
|
415
|
+
* per request, other than `McpRequestContext`, are per-request requirements
|
|
416
|
+
* of the result; see {@link Middleware} for how they are met.
|
|
417
|
+
*
|
|
418
|
+
* Failures must be `McpErrorBase` values. A middleware failure is sent as a
|
|
419
|
+
* JSON-RPC error with its `code`, `message` and `data`, never as a tool
|
|
420
|
+
* result. Pick custom codes from the implementation-defined range
|
|
421
|
+
* (-32000 to -32019): any numeric `code` is sent as is. Defects are logged,
|
|
422
|
+
* reported to the `ErrorReporter` and sent as `InternalError("Internal error")`.
|
|
423
|
+
* Interruption propagates.
|
|
424
|
+
*
|
|
425
|
+
* Local middleware runs inside global middleware, and middleware provided both
|
|
426
|
+
* locally and globally runs once. Middleware never runs for `initialize`. It
|
|
427
|
+
* runs for list requests only when it wraps a {@link visibility}, so that the
|
|
428
|
+
* visibility check can read the services it provides.
|
|
429
|
+
*
|
|
430
|
+
* **Example** (Resolving the current user per request)
|
|
431
|
+
*
|
|
432
|
+
* ```ts
|
|
433
|
+
* import { Context, Effect, Layer, Schema } from "effect"
|
|
434
|
+
* import { McpSchema, McpServer, Tool, Toolkit } from "effect/ai"
|
|
435
|
+
*
|
|
436
|
+
* class CurrentUser extends Context.Service<CurrentUser, { readonly id: string }>()("CurrentUser") {}
|
|
437
|
+
*
|
|
438
|
+
* class Unauthorized extends Schema.Error<Unauthorized>("Unauthorized")({
|
|
439
|
+
* ...McpSchema.McpErrorBase.fields,
|
|
440
|
+
* _tag: Schema.tag("Unauthorized"),
|
|
441
|
+
* code: Schema.tag(-32001)
|
|
442
|
+
* }) {}
|
|
443
|
+
*
|
|
444
|
+
* const WhoAmI = Tool.make("WhoAmI", { success: Schema.String, dependencies: [CurrentUser] })
|
|
445
|
+
* const Tools = Toolkit.make(WhoAmI)
|
|
446
|
+
*
|
|
447
|
+
* const Auth = McpServer.middleware<{ provides: CurrentUser }>()((effect, { headers }) => {
|
|
448
|
+
* const token = headers["authorization"]
|
|
449
|
+
* return token === undefined
|
|
450
|
+
* ? Effect.fail(new Unauthorized({ message: "Missing credentials" }))
|
|
451
|
+
* : Effect.provideService(effect, CurrentUser, { id: token })
|
|
452
|
+
* })
|
|
453
|
+
*
|
|
454
|
+
* const Registrations = McpServer.toolkit(Tools).pipe(
|
|
455
|
+
* Layer.provide(Auth.layer),
|
|
456
|
+
* Layer.provide(Tools.toLayer({
|
|
457
|
+
* WhoAmI: () => Effect.map(CurrentUser, (user) => user.id)
|
|
458
|
+
* }))
|
|
459
|
+
* )
|
|
460
|
+
* ```
|
|
461
|
+
*
|
|
462
|
+
* @stability unstable
|
|
463
|
+
* @category middleware
|
|
464
|
+
* @since 4.0.0
|
|
465
|
+
*/
|
|
466
|
+
export const middleware:
|
|
467
|
+
& middleware.Make<never>
|
|
468
|
+
& (<Config extends { provides?: any } = {}>() => middleware.Make<
|
|
469
|
+
Config extends { provides: infer P } ? P : never
|
|
470
|
+
>) = function() {
|
|
471
|
+
if (arguments.length === 0) {
|
|
472
|
+
return makeMiddleware as any
|
|
473
|
+
}
|
|
474
|
+
return makeMiddleware(arguments[0], arguments[1]) as any
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Types used by `middleware`.
|
|
479
|
+
*
|
|
480
|
+
* @stability unstable
|
|
481
|
+
* @category middleware
|
|
482
|
+
* @since 4.0.0
|
|
483
|
+
*/
|
|
484
|
+
export declare namespace middleware {
|
|
485
|
+
/**
|
|
486
|
+
* The middleware function.
|
|
487
|
+
*
|
|
488
|
+
* @stability unstable
|
|
489
|
+
* @category middleware
|
|
490
|
+
* @since 4.0.0
|
|
491
|
+
*/
|
|
492
|
+
export type Fn<Provides, E, R> = (
|
|
493
|
+
effect: Effect.Effect<MiddlewareSuccess, McpErrorBase, Types.NoInfer<Provides>>,
|
|
494
|
+
options: MiddlewareOptions
|
|
495
|
+
) => Effect.Effect<MiddlewareSuccess, E, R>
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* The overloads of a middleware constructor.
|
|
499
|
+
*
|
|
500
|
+
* @stability unstable
|
|
501
|
+
* @category middleware
|
|
502
|
+
* @since 4.0.0
|
|
503
|
+
*/
|
|
504
|
+
export type Make<Provides> = {
|
|
505
|
+
<E extends McpErrorBase, R, EX, RX, const Global extends boolean = false>(
|
|
506
|
+
middleware: Effect.Effect<Fn<Provides, E, R>, EX, RX>,
|
|
507
|
+
options?: { readonly global?: Global | undefined }
|
|
508
|
+
): Made<Global, {
|
|
509
|
+
provides: Provides
|
|
510
|
+
error: E
|
|
511
|
+
requires: Exclude<R, McpRequestContext>
|
|
512
|
+
layerError: EX
|
|
513
|
+
layerRequires: Exclude<RX, Scope.Scope>
|
|
514
|
+
}>
|
|
515
|
+
<E extends McpErrorBase, R, const Global extends boolean = false>(
|
|
516
|
+
middleware: Fn<Provides, E, R>,
|
|
517
|
+
options?: { readonly global?: Global | undefined }
|
|
518
|
+
): Made<Global, {
|
|
519
|
+
provides: Provides
|
|
520
|
+
error: E
|
|
521
|
+
requires: Exclude<R, McpRequestContext>
|
|
522
|
+
layerError: never
|
|
523
|
+
layerRequires: never
|
|
524
|
+
}>
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Creates middleware that hides registrations per request.
|
|
530
|
+
*
|
|
531
|
+
* **Details**
|
|
532
|
+
*
|
|
533
|
+
* The check runs for every registration the middleware is provided to, on list
|
|
534
|
+
* requests and on calls, reads, gets and completions. When it returns `false`
|
|
535
|
+
* the registration is left out of list results, and requests for it fail as if
|
|
536
|
+
* it was not registered.
|
|
537
|
+
*
|
|
538
|
+
* The result is a `Middleware` and composes like one. The check receives the
|
|
539
|
+
* same {@link MiddlewareOptions} as middleware, and services it reads per
|
|
540
|
+
* request, other than `McpRequestContext`, are met the same way. Scope a
|
|
541
|
+
* visibility to some tools by providing its layer to their toolkit only, or
|
|
542
|
+
* branch on `target`.
|
|
543
|
+
*
|
|
544
|
+
* On a list request, the check and the middleware outside the innermost
|
|
545
|
+
* visibility run once for each registration. Middleware inside it does not
|
|
546
|
+
* run. A failure of that middleware or of a check fails the whole list
|
|
547
|
+
* request. It never hides a registration.
|
|
548
|
+
*
|
|
549
|
+
* Unlike `EnabledWhen`, a visibility runs the middleware around it on list
|
|
550
|
+
* requests, and middleware sees requests for hidden registrations.
|
|
551
|
+
*
|
|
552
|
+
* **Example** (Hiding admin tools from other users)
|
|
553
|
+
*
|
|
554
|
+
* ```ts
|
|
555
|
+
* import { Context, Effect, Layer, Schema } from "effect"
|
|
556
|
+
* import { McpServer, Tool, Toolkit } from "effect/ai"
|
|
557
|
+
*
|
|
558
|
+
* class CurrentUser extends Context.Service<CurrentUser, { readonly isAdmin: boolean }>()("CurrentUser") {}
|
|
559
|
+
*
|
|
560
|
+
* const AdminTools = Toolkit.make(Tool.make("DeleteUser", { success: Schema.String }))
|
|
561
|
+
*
|
|
562
|
+
* const Auth = McpServer.middleware<{ provides: CurrentUser }>()((effect, { headers }) =>
|
|
563
|
+
* Effect.provideService(effect, CurrentUser, { isAdmin: headers["x-role"] === "admin" })
|
|
564
|
+
* )
|
|
565
|
+
* const AdminOnly = McpServer.visibility(() => Effect.map(CurrentUser, (user) => user.isAdmin))
|
|
566
|
+
*
|
|
567
|
+
* const Registrations = McpServer.toolkit(AdminTools).pipe(
|
|
568
|
+
* Layer.provide(AdminOnly.combine(Auth).layer),
|
|
569
|
+
* Layer.provide(AdminTools.toLayer({ DeleteUser: () => Effect.succeed("deleted") }))
|
|
570
|
+
* )
|
|
571
|
+
* ```
|
|
572
|
+
*
|
|
573
|
+
* @see {@link middleware} for providing the services a check reads
|
|
574
|
+
*
|
|
575
|
+
* @stability unstable
|
|
576
|
+
* @category middleware
|
|
577
|
+
* @since 4.0.0
|
|
578
|
+
*/
|
|
579
|
+
export const visibility: visibility.Make = ((
|
|
580
|
+
check: AnyVisibilityCheck | Effect.Effect<AnyVisibilityCheck, any, any>,
|
|
581
|
+
options?: { readonly global?: boolean | undefined }
|
|
582
|
+
) => makeMiddleware(Effect.isEffect(check) ? Effect.map(check, makeGate) : makeGate(check), options)) as any
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Types used by `visibility`.
|
|
586
|
+
*
|
|
587
|
+
* @stability unstable
|
|
588
|
+
* @category middleware
|
|
589
|
+
* @since 4.0.0
|
|
590
|
+
*/
|
|
591
|
+
export declare namespace visibility {
|
|
592
|
+
/**
|
|
593
|
+
* The visibility check.
|
|
594
|
+
*
|
|
595
|
+
* @stability unstable
|
|
596
|
+
* @category middleware
|
|
597
|
+
* @since 4.0.0
|
|
598
|
+
*/
|
|
599
|
+
export type Check<E, R> = (options: MiddlewareOptions) => Effect.Effect<boolean, E, R>
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* The overloads of `visibility`.
|
|
603
|
+
*
|
|
604
|
+
* @stability unstable
|
|
605
|
+
* @category middleware
|
|
606
|
+
* @since 4.0.0
|
|
607
|
+
*/
|
|
608
|
+
export type Make = {
|
|
609
|
+
<E extends McpErrorBase, R, EX, RX, const Global extends boolean = false>(
|
|
610
|
+
check: Effect.Effect<Check<E, R>, EX, RX>,
|
|
611
|
+
options?: { readonly global?: Global | undefined }
|
|
612
|
+
): Made<Global, {
|
|
613
|
+
provides: never
|
|
614
|
+
error: E
|
|
615
|
+
requires: Exclude<R, McpRequestContext>
|
|
616
|
+
layerError: EX
|
|
617
|
+
layerRequires: Exclude<RX, Scope.Scope>
|
|
618
|
+
}>
|
|
619
|
+
<E extends McpErrorBase, R, const Global extends boolean = false>(
|
|
620
|
+
check: Check<E, R>,
|
|
621
|
+
options?: { readonly global?: Global | undefined }
|
|
622
|
+
): Made<Global, {
|
|
623
|
+
provides: never
|
|
624
|
+
error: E
|
|
625
|
+
requires: Exclude<R, McpRequestContext>
|
|
626
|
+
layerError: never
|
|
627
|
+
layerRequires: never
|
|
628
|
+
}>
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
type AnyVisibilityCheck = visibility.Check<any, any>
|
|
633
|
+
|
|
634
|
+
// Raised by a visibility gate. It is left out of the types because `makeInvoke`
|
|
635
|
+
// replaces it with the not-found error of the request. It still has the shape
|
|
636
|
+
// of an MCP error, since middleware outside the gate sees it as one.
|
|
637
|
+
class Hidden extends Data.TaggedError("effect/ai/McpServer/Hidden")<{
|
|
638
|
+
readonly code: number
|
|
639
|
+
readonly message: string
|
|
640
|
+
}> {}
|
|
641
|
+
|
|
642
|
+
const failHidden = Effect.fail(
|
|
643
|
+
new Hidden({ code: McpSchema.INVALID_PARAMS_ERROR_CODE, message: "Not found" })
|
|
644
|
+
) as Effect.Effect<never>
|
|
645
|
+
|
|
646
|
+
// Marks the middleware functions created by `visibility`.
|
|
647
|
+
const gates = new WeakSet<AnyMiddlewareFn>()
|
|
648
|
+
|
|
649
|
+
const makeGate = (check: AnyVisibilityCheck): AnyMiddlewareFn => {
|
|
650
|
+
const gate: AnyMiddlewareFn = (effect, options) =>
|
|
651
|
+
Effect.flatMap(check(options), (visible) => visible ? effect : failHidden)
|
|
652
|
+
gates.add(gate)
|
|
653
|
+
return gate
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
type Made<Global extends boolean, Config extends MiddlewareConfig> = Global extends true
|
|
657
|
+
? MiddlewareLayer<Config, McpServer>
|
|
658
|
+
: Middleware<Config>
|
|
659
|
+
|
|
660
|
+
type AnyMiddlewareFn = middleware.Fn<any, any, any>
|
|
661
|
+
|
|
662
|
+
class MiddlewareFn extends Context.Service<MiddlewareFn, AnyMiddlewareFn>()("effect/ai/McpServer/MiddlewareFn") {}
|
|
663
|
+
|
|
664
|
+
const makeMiddleware = (
|
|
665
|
+
fn: AnyMiddlewareFn | Effect.Effect<AnyMiddlewareFn, any, any>,
|
|
666
|
+
options?: { readonly global?: boolean | undefined }
|
|
667
|
+
) => {
|
|
668
|
+
const middleware = new MiddlewareImpl(
|
|
669
|
+
Effect.isEffect(fn) ? Layer.effect(MiddlewareFn)(fn) : Layer.succeed(MiddlewareFn, fn)
|
|
670
|
+
)
|
|
671
|
+
return options?.global ? middleware.layerGlobal : middleware
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
let middlewareId = 0
|
|
675
|
+
|
|
676
|
+
class MiddlewareImpl {
|
|
677
|
+
readonly [MiddlewareTypeId] = {} as any
|
|
678
|
+
readonly layer: Layer.Layer<never, any, any>
|
|
679
|
+
readonly layerGlobal: Layer.Layer<never, any, any>
|
|
680
|
+
readonly layerFn: Layer.Layer<MiddlewareFn, any, any>
|
|
681
|
+
readonly dependencies: Layer.Layer<any, any, any> | undefined
|
|
682
|
+
|
|
683
|
+
constructor(
|
|
684
|
+
layerFn: Layer.Layer<MiddlewareFn, any, any>,
|
|
685
|
+
dependencies?: Layer.Layer<any, any, any> | undefined
|
|
686
|
+
) {
|
|
687
|
+
this.layerFn = layerFn
|
|
688
|
+
this.dependencies = dependencies
|
|
689
|
+
const contextKey = `${middlewareKeyPrefix}${++middlewareId}`
|
|
690
|
+
this.layer = Layer.effectContext(Effect.gen(function*() {
|
|
691
|
+
const stack: Array<AnyMiddlewareFn> = [yield* MiddlewareFn]
|
|
692
|
+
if (dependencies) {
|
|
693
|
+
const memoMap = yield* Layer.CurrentMemoMap
|
|
694
|
+
const scope = yield* Effect.scope
|
|
695
|
+
stack.push(...getMiddleware(yield* Layer.buildWithMemoMap(dependencies, memoMap, scope)))
|
|
696
|
+
}
|
|
697
|
+
return Context.makeUnsafe<never>(new Map([[contextKey, stack]]))
|
|
698
|
+
})).pipe(Layer.provide(layerFn))
|
|
699
|
+
this.layerGlobal = Layer.effectDiscard(Effect.gen(function*() {
|
|
700
|
+
const stack: ReadonlyArray<AnyMiddlewareFn> = Context.getOrUndefinedUnsafe(
|
|
701
|
+
yield* Effect.context<never>(),
|
|
702
|
+
contextKey as any
|
|
703
|
+
)!
|
|
704
|
+
const { globalMiddleware } = internalState.get(yield* McpServer)!
|
|
705
|
+
yield* Effect.acquireRelease(
|
|
706
|
+
Effect.sync(() => {
|
|
707
|
+
globalMiddleware.push(...stack)
|
|
708
|
+
}),
|
|
709
|
+
() =>
|
|
710
|
+
Effect.sync(() => {
|
|
711
|
+
for (const fn of stack) {
|
|
712
|
+
const index = globalMiddleware.indexOf(fn)
|
|
713
|
+
if (index !== -1) globalMiddleware.splice(index, 1)
|
|
714
|
+
}
|
|
715
|
+
})
|
|
716
|
+
)
|
|
717
|
+
})).pipe(Layer.provide(this.layer))
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
combine(other: Middleware<any>): Middleware<any> {
|
|
721
|
+
return new MiddlewareImpl(
|
|
722
|
+
this.layerFn,
|
|
723
|
+
this.dependencies ? Layer.provideMerge(this.dependencies, other.layer as any) : other.layer as any
|
|
724
|
+
) as any
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// The innermost middleware comes first.
|
|
729
|
+
const getMiddleware = (context: Context.Context<never>): ReadonlyArray<AnyMiddlewareFn> => {
|
|
730
|
+
const stacks: Array<ReadonlyArray<AnyMiddlewareFn>> = []
|
|
731
|
+
let maxLength = 0
|
|
732
|
+
for (const [key, value] of context.mapUnsafe) {
|
|
733
|
+
if (key.startsWith(middlewareKeyPrefix)) {
|
|
734
|
+
stacks.push(value)
|
|
735
|
+
maxLength = Math.max(maxLength, value.length)
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
const unique = new Set<AnyMiddlewareFn>()
|
|
739
|
+
for (let i = maxLength - 1; i >= 0; i--) {
|
|
740
|
+
for (const stack of stacks) {
|
|
741
|
+
if (i < stack.length) unique.add(stack[i])
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
return Arr.fromIterable(unique).reverse()
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
const isMcpError = (error: unknown): error is McpErrorBase =>
|
|
748
|
+
Predicate.hasProperty(error, "code") && typeof error.code === "number" &&
|
|
749
|
+
Predicate.hasProperty(error, "message") && typeof error.message === "string"
|
|
750
|
+
|
|
751
|
+
// Distinguishes handler failures from failures raised or rewritten by middleware.
|
|
752
|
+
const HandlerFailure = Context.Reference<boolean>("effect/ai/McpServer/HandlerFailure", {
|
|
753
|
+
defaultValue: () => false
|
|
754
|
+
})
|
|
755
|
+
const handlerFailure = Context.make(HandlerFailure, true)
|
|
756
|
+
|
|
757
|
+
const internalError = new InternalError({ message: "Internal error" })
|
|
758
|
+
|
|
759
|
+
const rejectWith = (error: McpErrorBase) =>
|
|
760
|
+
Effect.fail(new McpCore.RequestRejected({ code: error.code, message: error.message, data: error.data, error }))
|
|
761
|
+
|
|
762
|
+
type CallMethod = "tools/call" | "resources/read" | "prompts/get" | "completion/complete"
|
|
763
|
+
|
|
764
|
+
type ListMethod = Exclude<MiddlewareMethod, CallMethod>
|
|
765
|
+
|
|
766
|
+
interface NotFoundErrors {
|
|
767
|
+
readonly "tools/call": McpCore.ToolNotFound
|
|
768
|
+
readonly "resources/read": McpCore.ResourceNotFound
|
|
769
|
+
readonly "prompts/get": McpCore.PromptNotFound
|
|
770
|
+
readonly "completion/complete": InvalidParams
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
const notFound = (method: CallMethod, target: string): NotFoundErrors[CallMethod] => {
|
|
774
|
+
switch (method) {
|
|
775
|
+
case "tools/call":
|
|
776
|
+
return new McpCore.ToolNotFound({ name: target })
|
|
777
|
+
case "resources/read":
|
|
778
|
+
return new McpCore.ResourceNotFound({ uri: target })
|
|
779
|
+
case "prompts/get":
|
|
780
|
+
return new McpCore.PromptNotFound({ name: target })
|
|
781
|
+
case "completion/complete":
|
|
782
|
+
return new InvalidParams({ message: "Unknown completion reference or argument" })
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
const isHidden = (error: unknown): error is Hidden => error instanceof Hidden
|
|
787
|
+
|
|
788
|
+
// Recovers a request rejected by a visibility gate. Any other cause, including
|
|
789
|
+
// one that also holds an interrupt, is propagated unchanged.
|
|
790
|
+
const catchHidden =
|
|
791
|
+
<B, E2>(onHidden: () => Effect.Effect<B, E2>) =>
|
|
792
|
+
<A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A | B, Exclude<E, Hidden> | E2, R> =>
|
|
793
|
+
Effect.catchCause(self, (cause): Effect.Effect<B, Exclude<E, Hidden> | E2> => {
|
|
794
|
+
const failure = Cause.findFail(cause)
|
|
795
|
+
return !Cause.hasInterrupts(cause) && Result.isSuccess(failure) && isHidden(failure.success.error)
|
|
796
|
+
? onHidden()
|
|
797
|
+
: Effect.failCause(cause as Cause.Cause<Exclude<E, Hidden>>)
|
|
798
|
+
})
|
|
799
|
+
|
|
800
|
+
// The innermost middleware comes first. Middleware provided both locally and
|
|
801
|
+
// globally runs once, at its outermost position.
|
|
802
|
+
const middlewareStack = (
|
|
803
|
+
localMiddleware: ReadonlyArray<AnyMiddlewareFn>,
|
|
804
|
+
globalMiddleware: ReadonlyArray<AnyMiddlewareFn>
|
|
805
|
+
): ReadonlyArray<AnyMiddlewareFn> => {
|
|
806
|
+
if (globalMiddleware.length === 0) {
|
|
807
|
+
return localMiddleware
|
|
808
|
+
}
|
|
809
|
+
if (localMiddleware.length === 0) {
|
|
810
|
+
return globalMiddleware
|
|
811
|
+
}
|
|
812
|
+
const stack = [...localMiddleware, ...globalMiddleware]
|
|
813
|
+
return stack.filter((fn, index) => stack.lastIndexOf(fn) === index)
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// Runs a handler inside middleware. The handler's own failures pass through, a
|
|
817
|
+
// visibility gate fails with `Hidden`, and other failures become
|
|
818
|
+
// `RequestRejected`: middleware failures as JSON-RPC errors, anything else as
|
|
819
|
+
// a reported internal error.
|
|
820
|
+
const runMiddleware = <A, E>(
|
|
821
|
+
handler: Effect.Effect<A, E, any>,
|
|
822
|
+
middleware: ReadonlyArray<AnyMiddlewareFn>,
|
|
823
|
+
invocation: McpCore.McpInvocation,
|
|
824
|
+
request: Pick<MiddlewareOptions, "method" | "target" | "payload">
|
|
825
|
+
): Effect.Effect<A, E | Hidden | McpCore.RequestRejected> => {
|
|
826
|
+
const effect = middleware.length === 0 ? handler : Effect.withFiber((fiber) => {
|
|
827
|
+
const headers = Context.getOrUndefined(fiber.context, HttpServerRequest.HttpServerRequest)?.headers ??
|
|
828
|
+
Headers.empty
|
|
829
|
+
const options: MiddlewareOptions = {
|
|
830
|
+
...request,
|
|
831
|
+
requestContext: invocation.requestContext,
|
|
832
|
+
headers,
|
|
833
|
+
sessionId: headers[MCP_SESSION_ID_HEADER]
|
|
834
|
+
}
|
|
835
|
+
const handled = Effect.catchCause(handler, (cause) => Effect.failCause(Cause.annotate(cause, handlerFailure)))
|
|
836
|
+
return middleware.reduce((effect: Effect.Effect<any, any, any>, fn) => fn(effect, options), handled)
|
|
837
|
+
})
|
|
838
|
+
return provideInvocationContext(effect, invocation).pipe(
|
|
839
|
+
Effect.catchCause((cause): Effect.Effect<never, E | Hidden | McpCore.RequestRejected> => {
|
|
840
|
+
if (Cause.hasInterrupts(cause)) {
|
|
841
|
+
return Effect.failCause(cause)
|
|
842
|
+
}
|
|
843
|
+
const failure = Cause.findFail(cause)
|
|
844
|
+
if (Result.isSuccess(failure) && !Cause.hasDies(cause)) {
|
|
845
|
+
const error = failure.success.error
|
|
846
|
+
if (isHidden(error)) {
|
|
847
|
+
return Effect.fail(error)
|
|
848
|
+
}
|
|
849
|
+
if (middleware.length === 0 || Context.get(Cause.reasonAnnotations(failure.success), HandlerFailure)) {
|
|
850
|
+
return Effect.failCause(cause)
|
|
851
|
+
}
|
|
852
|
+
if (isMcpError(error)) {
|
|
853
|
+
return rejectWith(error)
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
return Effect.logError(cause).pipe(
|
|
857
|
+
Effect.andThen(ErrorReporter.report(cause)),
|
|
858
|
+
Effect.andThen(rejectWith(internalError))
|
|
859
|
+
)
|
|
860
|
+
})
|
|
861
|
+
) as Effect.Effect<A, E | Hidden | McpCore.RequestRejected>
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
// Request services override captured services; global middleware wraps local middleware.
|
|
865
|
+
const makeInvoke = (
|
|
866
|
+
context: Context.Context<never> | undefined,
|
|
867
|
+
globalMiddleware: ReadonlyArray<AnyMiddlewareFn>
|
|
868
|
+
) => {
|
|
869
|
+
const services = context === undefined ? Context.empty() : omitRequestServices(context)
|
|
870
|
+
const localMiddleware = context === undefined ? [] : getMiddleware(context)
|
|
871
|
+
const invoke = <A, E, M extends CallMethod>(
|
|
872
|
+
handler: Effect.Effect<A, E, any>,
|
|
873
|
+
invocation: McpCore.McpInvocation,
|
|
874
|
+
request: {
|
|
875
|
+
readonly method: M
|
|
876
|
+
readonly target: string
|
|
877
|
+
readonly payload: unknown
|
|
878
|
+
}
|
|
879
|
+
): Effect.Effect<A, E | NotFoundErrors[M] | McpCore.RequestRejected> =>
|
|
880
|
+
runMiddleware(
|
|
881
|
+
services.mapUnsafe.size === 0
|
|
882
|
+
? handler
|
|
883
|
+
: Effect.updateContext(handler, (context: Context.Context<any>) => Context.merge(services, context)),
|
|
884
|
+
middlewareStack(localMiddleware, globalMiddleware),
|
|
885
|
+
invocation,
|
|
886
|
+
request
|
|
887
|
+
).pipe(
|
|
888
|
+
catchHidden(() => Effect.fail(notFound(request.method, request.target) as NotFoundErrors[M]))
|
|
889
|
+
) as Effect.Effect<A, E | NotFoundErrors[M] | McpCore.RequestRejected>
|
|
890
|
+
// On list requests only the middleware outside the innermost visibility runs.
|
|
891
|
+
const visible = (method: ListMethod, target: string): McpCore.Visible => (invocation) => {
|
|
892
|
+
const middleware = middlewareStack(localMiddleware, globalMiddleware)
|
|
893
|
+
const innermost = middleware.findIndex((fn) => gates.has(fn))
|
|
894
|
+
if (innermost === -1) {
|
|
895
|
+
return Effect.succeed(true)
|
|
896
|
+
}
|
|
897
|
+
return runMiddleware(Effect.void, middleware.slice(innermost), invocation, { method, target, payload: undefined })
|
|
898
|
+
.pipe(
|
|
899
|
+
Effect.as(true),
|
|
900
|
+
catchHidden(() => Effect.succeed(false))
|
|
901
|
+
)
|
|
902
|
+
}
|
|
903
|
+
return { invoke, visible }
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// Applies the `EnabledWhen` annotation of a registration.
|
|
907
|
+
const isEnabled = (annotations: Context.Context<never>) => {
|
|
908
|
+
const enabledWhen = Context.getOrUndefined(annotations, EnabledWhen)
|
|
909
|
+
return (profile: McpCore.NegotiatedProtocolProfile<string>): boolean =>
|
|
910
|
+
enabledWhen === undefined || enabledWhen({
|
|
911
|
+
protocolVersion: profile.protocolVersion,
|
|
912
|
+
capabilities: profile.clientCapabilities,
|
|
913
|
+
clientInfo: profile.clientInfo
|
|
914
|
+
})
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
const rejectedError = (rejected: McpCore.RequestRejected) => Effect.fail(rejected.error)
|
|
918
|
+
|
|
202
919
|
/**
|
|
203
920
|
* Service that stores and serves an MCP server's registered tools, resources,
|
|
204
921
|
* prompts, completions, and outgoing notifications.
|
|
@@ -225,6 +942,7 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
225
942
|
readonly addTool: (options: {
|
|
226
943
|
readonly tool: McpTool
|
|
227
944
|
readonly annotations: Context.Context<never>
|
|
945
|
+
readonly services?: Context.Context<never> | undefined
|
|
228
946
|
readonly handle: (
|
|
229
947
|
payload: any
|
|
230
948
|
) => Effect.Effect<
|
|
@@ -235,7 +953,7 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
235
953
|
}) => Effect.Effect<void>
|
|
236
954
|
readonly callTool: (
|
|
237
955
|
requests: typeof CallTool.payloadSchema.Type
|
|
238
|
-
) => Effect.Effect<CallToolResult, InternalError | InvalidParams, McpServerClient>
|
|
956
|
+
) => Effect.Effect<CallToolResult, McpErrorBase | InternalError | InvalidParams, McpServerClient>
|
|
239
957
|
|
|
240
958
|
readonly resources: ReadonlyArray<{
|
|
241
959
|
readonly resource: Resource
|
|
@@ -244,6 +962,7 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
244
962
|
readonly addResource: (options: {
|
|
245
963
|
readonly resource: Resource
|
|
246
964
|
readonly annotations: Context.Context<never>
|
|
965
|
+
readonly services?: Context.Context<never> | undefined
|
|
247
966
|
readonly handle: Effect.Effect<
|
|
248
967
|
ReadResourceResult,
|
|
249
968
|
InternalError,
|
|
@@ -259,6 +978,7 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
259
978
|
options: {
|
|
260
979
|
readonly template: ResourceTemplate
|
|
261
980
|
readonly annotations: Context.Context<never>
|
|
981
|
+
readonly services?: Context.Context<never> | undefined
|
|
262
982
|
readonly routerPath: string
|
|
263
983
|
readonly completions: Record<
|
|
264
984
|
string,
|
|
@@ -289,6 +1009,7 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
289
1009
|
readonly addPrompt: (options: {
|
|
290
1010
|
readonly prompt: Prompt
|
|
291
1011
|
readonly annotations: Context.Context<never>
|
|
1012
|
+
readonly services?: Context.Context<never> | undefined
|
|
292
1013
|
readonly completions: Record<
|
|
293
1014
|
string,
|
|
294
1015
|
(
|
|
@@ -302,11 +1023,11 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
302
1023
|
}) => Effect.Effect<void>
|
|
303
1024
|
readonly getPromptResult: (
|
|
304
1025
|
request: typeof GetPrompt.payloadSchema.Type
|
|
305
|
-
) => Effect.Effect<GetPromptResult, InternalError | InvalidParams, McpServerClient>
|
|
1026
|
+
) => Effect.Effect<GetPromptResult, McpErrorBase | InternalError | InvalidParams, McpServerClient>
|
|
306
1027
|
|
|
307
1028
|
readonly completion: (
|
|
308
1029
|
complete: typeof Complete.payloadSchema.Type
|
|
309
|
-
) => Effect.Effect<CompleteResult, InvalidParams | InternalError, McpServerClient>
|
|
1030
|
+
) => Effect.Effect<CompleteResult, McpErrorBase | InvalidParams | InternalError, McpServerClient>
|
|
310
1031
|
}>()("effect/ai/McpServer") {
|
|
311
1032
|
/**
|
|
312
1033
|
* Builds an MCP server service from registered tools, prompts, resources, and completions.
|
|
@@ -333,6 +1054,7 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
333
1054
|
readonly annotations: Context.Context<never>
|
|
334
1055
|
}> = []
|
|
335
1056
|
const notificationsQueue = yield* Queue.make<QueuedServerNotification>()
|
|
1057
|
+
const globalMiddleware: Array<AnyMiddlewareFn> = []
|
|
336
1058
|
const notificationDelivery = { consumers: 0, listChangeRevision: 0, requestEndpoints: 0 }
|
|
337
1059
|
// With only request-scoped endpoints, no long-lived server ever takes from the shared queue.
|
|
338
1060
|
const withoutSharedConsumer = () =>
|
|
@@ -431,22 +1153,20 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
431
1153
|
} else {
|
|
432
1154
|
tools[existingIndex] = options
|
|
433
1155
|
}
|
|
434
|
-
const
|
|
1156
|
+
const { invoke, visible } = makeInvoke(options.services, globalMiddleware)
|
|
435
1157
|
yield* internalCore.tools.register({
|
|
436
1158
|
descriptor: new McpTool({
|
|
437
1159
|
...options.tool,
|
|
438
1160
|
title: options.tool.title ?? options.tool.annotations?.title
|
|
439
1161
|
}),
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
{
|
|
443
|
-
protocolVersion: profile.protocolVersion,
|
|
444
|
-
capabilities: profile.clientCapabilities,
|
|
445
|
-
clientInfo: profile.clientInfo
|
|
446
|
-
}
|
|
447
|
-
),
|
|
1162
|
+
visible: visible("tools/list", options.tool.name),
|
|
1163
|
+
isVisible: isEnabled(options.annotations),
|
|
448
1164
|
handle: (call, invocation) =>
|
|
449
|
-
|
|
1165
|
+
invoke(options.handle(call.arguments), invocation, {
|
|
1166
|
+
method: "tools/call",
|
|
1167
|
+
target: call.name,
|
|
1168
|
+
payload: call
|
|
1169
|
+
}).pipe(
|
|
450
1170
|
Effect.catchTags({
|
|
451
1171
|
InternalError: (error) =>
|
|
452
1172
|
Effect.fail(
|
|
@@ -481,12 +1201,14 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
481
1201
|
request,
|
|
482
1202
|
McpProtocolInternal.invocationFromClient(client)
|
|
483
1203
|
).pipe(
|
|
484
|
-
Effect.
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
1204
|
+
Effect.catch((error) =>
|
|
1205
|
+
error._tag === "RequestRejected" ? rejectedError(error) : Effect.fail(
|
|
1206
|
+
new InvalidParams({
|
|
1207
|
+
message: error._tag === "ToolNotFound"
|
|
1208
|
+
? `Tool '${error.name}' not found`
|
|
1209
|
+
: error.message
|
|
1210
|
+
})
|
|
1211
|
+
)
|
|
490
1212
|
)
|
|
491
1213
|
)
|
|
492
1214
|
if (result._tag === "InputRequired") {
|
|
@@ -507,80 +1229,87 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
507
1229
|
} else {
|
|
508
1230
|
resources[existingIndex] = options
|
|
509
1231
|
}
|
|
1232
|
+
const { invoke, visible } = makeInvoke(options.services, globalMiddleware)
|
|
510
1233
|
yield* internalCore.resources.register({
|
|
511
1234
|
descriptor: options.resource,
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
1235
|
+
visible: visible("resources/list", options.resource.uri),
|
|
1236
|
+
isVisible: isEnabled(options.annotations),
|
|
1237
|
+
read: (invocation) =>
|
|
1238
|
+
invoke(options.handle, invocation, {
|
|
1239
|
+
method: "resources/read",
|
|
1240
|
+
target: options.resource.uri,
|
|
1241
|
+
payload: { uri: options.resource.uri }
|
|
518
1242
|
})
|
|
519
|
-
},
|
|
520
|
-
read: (invocation) => provideInvocationContext(options.handle, invocation)
|
|
521
1243
|
})
|
|
522
1244
|
yield* notifications.client["notifications/resources/list_changed"]({})
|
|
523
1245
|
}),
|
|
524
|
-
addResourceTemplate: Effect.fnUntraced(
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
if (existingIndex === -1) {
|
|
529
|
-
resourceTemplates.push({ template, annotations })
|
|
530
|
-
} else {
|
|
531
|
-
resourceTemplates[existingIndex] = { template, annotations }
|
|
532
|
-
}
|
|
533
|
-
const templateMatcher = makeUriMatcher<true>()
|
|
534
|
-
templateMatcher.add(routerPath, true)
|
|
535
|
-
yield* internalCore.resources.registerTemplate({
|
|
536
|
-
descriptor: template,
|
|
537
|
-
isVisible: (profile) => {
|
|
538
|
-
const enabledWhen = Context.getOrUndefined(annotations, EnabledWhen)
|
|
539
|
-
return enabledWhen === undefined || enabledWhen({
|
|
540
|
-
protocolVersion: profile.protocolVersion,
|
|
541
|
-
capabilities: profile.clientCapabilities,
|
|
542
|
-
clientInfo: profile.clientInfo
|
|
543
|
-
})
|
|
544
|
-
},
|
|
545
|
-
match: (uri) => {
|
|
546
|
-
const match = templateMatcher.find(uri)
|
|
547
|
-
if (match === undefined) {
|
|
548
|
-
return undefined
|
|
549
|
-
}
|
|
550
|
-
const params: Array<string> = []
|
|
551
|
-
for (const key of Object.keys(match.params)) {
|
|
552
|
-
params[Number(key)] = match.params[key]!
|
|
553
|
-
}
|
|
554
|
-
return params
|
|
555
|
-
},
|
|
556
|
-
read: (uri, params, invocation) => provideInvocationContext(handle(uri, Array.from(params)), invocation)
|
|
557
|
-
})
|
|
558
|
-
for (const [param, handle] of Object.entries(completions)) {
|
|
559
|
-
yield* internalCore.completions.register(
|
|
560
|
-
`resource/${template.uriTemplate}/${param}`,
|
|
561
|
-
(request, invocation) =>
|
|
562
|
-
provideInvocationContext(handle(request.argument.value, request.context), invocation).pipe(
|
|
563
|
-
Effect.map((result) => ({
|
|
564
|
-
values: result.completion.values,
|
|
565
|
-
total: result.completion.total,
|
|
566
|
-
hasMore: result.completion.hasMore,
|
|
567
|
-
metadata: result._meta
|
|
568
|
-
}))
|
|
569
|
-
)
|
|
1246
|
+
addResourceTemplate: Effect.fnUntraced(
|
|
1247
|
+
function*({ annotations, completions, handle, routerPath, services, template }) {
|
|
1248
|
+
const existingIndex = resourceTemplates.findIndex(({ template: current }) =>
|
|
1249
|
+
current.uriTemplate === template.uriTemplate
|
|
570
1250
|
)
|
|
1251
|
+
if (existingIndex === -1) {
|
|
1252
|
+
resourceTemplates.push({ template, annotations })
|
|
1253
|
+
} else {
|
|
1254
|
+
resourceTemplates[existingIndex] = { template, annotations }
|
|
1255
|
+
}
|
|
1256
|
+
const { invoke, visible } = makeInvoke(services, globalMiddleware)
|
|
1257
|
+
const templateMatcher = makeUriMatcher<true>()
|
|
1258
|
+
templateMatcher.add(routerPath, true)
|
|
1259
|
+
yield* internalCore.resources.registerTemplate({
|
|
1260
|
+
descriptor: template,
|
|
1261
|
+
visible: visible("resources/templates/list", template.uriTemplate),
|
|
1262
|
+
isVisible: isEnabled(annotations),
|
|
1263
|
+
match: (uri) => {
|
|
1264
|
+
const match = templateMatcher.find(uri)
|
|
1265
|
+
if (match === undefined) {
|
|
1266
|
+
return undefined
|
|
1267
|
+
}
|
|
1268
|
+
const params: Array<string> = []
|
|
1269
|
+
for (const key of Object.keys(match.params)) {
|
|
1270
|
+
params[Number(key)] = match.params[key]!
|
|
1271
|
+
}
|
|
1272
|
+
return params
|
|
1273
|
+
},
|
|
1274
|
+
read: (uri, params, invocation) =>
|
|
1275
|
+
invoke(handle(uri, Array.from(params)), invocation, {
|
|
1276
|
+
method: "resources/read",
|
|
1277
|
+
target: uri,
|
|
1278
|
+
payload: { uri }
|
|
1279
|
+
})
|
|
1280
|
+
})
|
|
1281
|
+
for (const [param, handle] of Object.entries(completions)) {
|
|
1282
|
+
yield* internalCore.completions.register(
|
|
1283
|
+
`resource/${template.uriTemplate}/${param}`,
|
|
1284
|
+
(request, invocation) =>
|
|
1285
|
+
invoke(handle(request.argument.value, request.context), invocation, {
|
|
1286
|
+
method: "completion/complete",
|
|
1287
|
+
target: template.uriTemplate,
|
|
1288
|
+
payload: request
|
|
1289
|
+
}).pipe(
|
|
1290
|
+
Effect.map((result) => ({
|
|
1291
|
+
values: result.completion.values,
|
|
1292
|
+
total: result.completion.total,
|
|
1293
|
+
hasMore: result.completion.hasMore,
|
|
1294
|
+
metadata: result._meta
|
|
1295
|
+
}))
|
|
1296
|
+
)
|
|
1297
|
+
)
|
|
1298
|
+
}
|
|
1299
|
+
yield* notifications.client["notifications/resources/list_changed"]({})
|
|
571
1300
|
}
|
|
572
|
-
|
|
573
|
-
}),
|
|
1301
|
+
),
|
|
574
1302
|
findResource: Effect.fnUntraced(function*(uri) {
|
|
575
1303
|
const client = yield* McpServerClient
|
|
576
1304
|
return yield* internalCore.resources.read(
|
|
577
1305
|
uri,
|
|
578
1306
|
McpProtocolInternal.invocationFromClient(client)
|
|
579
1307
|
).pipe(
|
|
580
|
-
Effect.
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
1308
|
+
Effect.catchTags({
|
|
1309
|
+
ResourceNotFound: (error) =>
|
|
1310
|
+
Effect.fail(new InvalidParams({ message: `Resource '${error.uri}' not found` })),
|
|
1311
|
+
RequestRejected: rejectedError
|
|
1312
|
+
})
|
|
584
1313
|
)
|
|
585
1314
|
}),
|
|
586
1315
|
get prompts() {
|
|
@@ -593,18 +1322,17 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
593
1322
|
} else {
|
|
594
1323
|
prompts[existingIndex] = options
|
|
595
1324
|
}
|
|
1325
|
+
const { invoke, visible } = makeInvoke(options.services, globalMiddleware)
|
|
596
1326
|
yield* internalCore.prompts.register({
|
|
597
1327
|
descriptor: options.prompt,
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
return enabledWhen === undefined || enabledWhen({
|
|
601
|
-
protocolVersion: profile.protocolVersion,
|
|
602
|
-
capabilities: profile.clientCapabilities,
|
|
603
|
-
clientInfo: profile.clientInfo
|
|
604
|
-
})
|
|
605
|
-
},
|
|
1328
|
+
visible: visible("prompts/list", options.prompt.name),
|
|
1329
|
+
isVisible: isEnabled(options.annotations),
|
|
606
1330
|
get: (params, invocation) =>
|
|
607
|
-
|
|
1331
|
+
invoke(options.handle(params), invocation, {
|
|
1332
|
+
method: "prompts/get",
|
|
1333
|
+
target: options.prompt.name,
|
|
1334
|
+
payload: { name: options.prompt.name, arguments: params }
|
|
1335
|
+
}).pipe(
|
|
608
1336
|
Effect.map((result) =>
|
|
609
1337
|
Predicate.isTagged(result, "InputRequired")
|
|
610
1338
|
? McpCore.OperationOutcome.InputRequired(result)
|
|
@@ -616,7 +1344,11 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
616
1344
|
yield* internalCore.completions.register(
|
|
617
1345
|
`prompt/${options.prompt.name}/${param}`,
|
|
618
1346
|
(request, invocation) =>
|
|
619
|
-
|
|
1347
|
+
invoke(handle(request.argument.value, request.context), invocation, {
|
|
1348
|
+
method: "completion/complete",
|
|
1349
|
+
target: options.prompt.name,
|
|
1350
|
+
payload: request
|
|
1351
|
+
}).pipe(
|
|
620
1352
|
Effect.map((result) => ({
|
|
621
1353
|
values: result.completion.values,
|
|
622
1354
|
total: result.completion.total,
|
|
@@ -635,7 +1367,10 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
635
1367
|
params ?? {},
|
|
636
1368
|
McpProtocolInternal.invocationFromClient(client)
|
|
637
1369
|
).pipe(
|
|
638
|
-
Effect.
|
|
1370
|
+
Effect.catchTags({
|
|
1371
|
+
PromptNotFound: () => new InvalidParams({ message: `Prompt '${name}' not found` }),
|
|
1372
|
+
RequestRejected: rejectedError
|
|
1373
|
+
})
|
|
639
1374
|
)
|
|
640
1375
|
return outcome._tag === "Complete"
|
|
641
1376
|
? outcome.value
|
|
@@ -650,7 +1385,9 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
650
1385
|
: { type: "prompt", name: ref.name },
|
|
651
1386
|
argument: complete.argument,
|
|
652
1387
|
context: complete.context
|
|
653
|
-
}, McpProtocolInternal.invocationFromClient(client))
|
|
1388
|
+
}, McpProtocolInternal.invocationFromClient(client)).pipe(
|
|
1389
|
+
Effect.catchTag("RequestRejected", rejectedError)
|
|
1390
|
+
)
|
|
654
1391
|
return {
|
|
655
1392
|
_meta: result.metadata,
|
|
656
1393
|
completion: {
|
|
@@ -661,17 +1398,28 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
661
1398
|
}
|
|
662
1399
|
})
|
|
663
1400
|
})
|
|
664
|
-
internalState.set(service, {
|
|
1401
|
+
internalState.set(service, {
|
|
1402
|
+
core: internalCore,
|
|
1403
|
+
notifications: notificationsQueue,
|
|
1404
|
+
notificationDelivery,
|
|
1405
|
+
globalMiddleware
|
|
1406
|
+
})
|
|
665
1407
|
return service
|
|
666
1408
|
})
|
|
667
1409
|
|
|
668
1410
|
/**
|
|
669
|
-
* Layer that provides the MCP server
|
|
1411
|
+
* Layer that provides the MCP server service.
|
|
1412
|
+
*
|
|
1413
|
+
* **Details**
|
|
1414
|
+
*
|
|
1415
|
+
* It doesn't run a transport or discharge request-level dependencies. Use it
|
|
1416
|
+
* to call registrations in process, providing their request-level
|
|
1417
|
+
* dependencies with MCP middleware.
|
|
670
1418
|
*
|
|
671
1419
|
* @stability unstable
|
|
672
1420
|
* @since 4.0.0
|
|
673
1421
|
*/
|
|
674
|
-
static readonly layer: Layer.Layer<McpServer
|
|
1422
|
+
static readonly layer: Layer.Layer<McpServer> = Layer.effect(McpServer)(McpServer.make)
|
|
675
1423
|
}
|
|
676
1424
|
|
|
677
1425
|
const MCP_SESSION_ID_HEADER = "mcp-session-id"
|
|
@@ -693,6 +1441,82 @@ class McpClientKey extends Data.Class<{
|
|
|
693
1441
|
readonly profile: McpCore.NegotiatedProtocolProfile<string>
|
|
694
1442
|
}> {}
|
|
695
1443
|
|
|
1444
|
+
/**
|
|
1445
|
+
* A client cache hint for one kind of `v2026_07_28` result.
|
|
1446
|
+
*
|
|
1447
|
+
* **Details**
|
|
1448
|
+
*
|
|
1449
|
+
* `ttl` is how long a client may treat the result as fresh. It is sent as a
|
|
1450
|
+
* whole number of milliseconds, rounded down, so it must be finite,
|
|
1451
|
+
* nonnegative and at most `Number.MAX_SAFE_INTEGER` milliseconds. Only
|
|
1452
|
+
* `"private"` scope is supported, so shared caches must not store the result.
|
|
1453
|
+
*
|
|
1454
|
+
* @stability unstable
|
|
1455
|
+
* @category models
|
|
1456
|
+
* @since 4.1.0
|
|
1457
|
+
*/
|
|
1458
|
+
export interface CacheHint {
|
|
1459
|
+
readonly ttl: Duration.Input
|
|
1460
|
+
readonly cacheScope: "private"
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
/**
|
|
1464
|
+
* Client cache hints for `v2026_07_28` discovery and list results.
|
|
1465
|
+
*
|
|
1466
|
+
* **Details**
|
|
1467
|
+
*
|
|
1468
|
+
* Each entry sets the freshness and `cacheScope` of one result kind:
|
|
1469
|
+
* `server/discover`, `tools/list`, `resources/list`,
|
|
1470
|
+
* `resources/templates/list` and `prompts/list`. Omitted entries, and
|
|
1471
|
+
* `resources/read` results, keep `{ ttlMs: 0, cacheScope: "private" }`.
|
|
1472
|
+
* Earlier protocol revisions have no cache hints and ignore this option.
|
|
1473
|
+
*
|
|
1474
|
+
* These are hints for clients. The server does not cache results, and
|
|
1475
|
+
* visibility and invocation checks still run on every request.
|
|
1476
|
+
*
|
|
1477
|
+
* **Gotchas**
|
|
1478
|
+
*
|
|
1479
|
+
* A positive `ttl` lets a client keep showing a list after registrations or
|
|
1480
|
+
* per-request visibility change, until the hint expires. Private scope does
|
|
1481
|
+
* not key a client's cache by user, so a client shared between users can
|
|
1482
|
+
* reuse one user's list for another.
|
|
1483
|
+
*
|
|
1484
|
+
* @stability unstable
|
|
1485
|
+
* @category models
|
|
1486
|
+
* @since 4.1.0
|
|
1487
|
+
*/
|
|
1488
|
+
export interface CacheHints {
|
|
1489
|
+
readonly discover?: CacheHint | undefined
|
|
1490
|
+
readonly tools?: CacheHint | undefined
|
|
1491
|
+
readonly resources?: CacheHint | undefined
|
|
1492
|
+
readonly resourceTemplates?: CacheHint | undefined
|
|
1493
|
+
readonly prompts?: CacheHint | undefined
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
// Converts each hint to the wire's nonnegative integer `ttlMs` once, when the server is built.
|
|
1497
|
+
const normalizeCacheHints = (
|
|
1498
|
+
cacheHints: CacheHints | undefined
|
|
1499
|
+
): Effect.Effect<McpProtocolInternal.CacheHints | undefined, Cause.IllegalArgumentError> => {
|
|
1500
|
+
if (cacheHints === undefined) return Effect.succeed(undefined)
|
|
1501
|
+
const normalized: Record<string, { readonly ttlMs: number; readonly cacheScope: "private" }> = {}
|
|
1502
|
+
for (const [name, hint] of Object.entries(cacheHints)) {
|
|
1503
|
+
if (hint === undefined) continue
|
|
1504
|
+
const ttlMs = Option.match(Duration.fromInput(hint.ttl), {
|
|
1505
|
+
onNone: () => NaN,
|
|
1506
|
+
onSome: (ttl) => Math.floor(Duration.toMillis(ttl))
|
|
1507
|
+
})
|
|
1508
|
+
if (!Number.isSafeInteger(ttlMs) || ttlMs < 0 || hint.cacheScope !== "private") {
|
|
1509
|
+
return Effect.fail(
|
|
1510
|
+
new Cause.IllegalArgumentError(
|
|
1511
|
+
`McpServer cacheHints.${name} must have a finite, nonnegative ttl and a "private" cacheScope`
|
|
1512
|
+
)
|
|
1513
|
+
)
|
|
1514
|
+
}
|
|
1515
|
+
normalized[name] = { ttlMs, cacheScope: "private" }
|
|
1516
|
+
}
|
|
1517
|
+
return Effect.succeed(normalized)
|
|
1518
|
+
}
|
|
1519
|
+
|
|
696
1520
|
/**
|
|
697
1521
|
* Runs an MCP server over the current `RpcServer.Protocol`.
|
|
698
1522
|
*
|
|
@@ -715,6 +1539,7 @@ export const run: (options: {
|
|
|
715
1539
|
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
716
1540
|
readonly protocols: Arr.NonEmptyReadonlyArray<McpProtocol.ProtocolAdapter>
|
|
717
1541
|
readonly extensions?: ServerExtensions | undefined
|
|
1542
|
+
readonly cacheHints?: CacheHints | undefined
|
|
718
1543
|
}) => Effect.Effect<
|
|
719
1544
|
never,
|
|
720
1545
|
Cause.IllegalArgumentError,
|
|
@@ -728,12 +1553,14 @@ export const run: (options: {
|
|
|
728
1553
|
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
729
1554
|
readonly protocols: Arr.NonEmptyReadonlyArray<McpProtocol.ProtocolAdapter>
|
|
730
1555
|
readonly extensions?: ServerExtensions | undefined
|
|
1556
|
+
readonly cacheHints?: CacheHints | undefined
|
|
731
1557
|
}) {
|
|
1558
|
+
const cacheHints = yield* normalizeCacheHints(options.cacheHints)
|
|
732
1559
|
const runtimeOption = yield* Effect.serviceOption(McpRuntime.ServerRuntime)
|
|
733
1560
|
const runtime = Option.isSome(runtimeOption)
|
|
734
1561
|
? runtimeOption.value
|
|
735
1562
|
: yield* McpRuntime.make(options.protocols)
|
|
736
|
-
return yield* runWithRuntime(options, runtime, "custom")
|
|
1563
|
+
return yield* runWithRuntime({ ...options, cacheHints }, runtime, "custom")
|
|
737
1564
|
})
|
|
738
1565
|
|
|
739
1566
|
const runWithRuntime = Effect.fnUntraced(function*(
|
|
@@ -745,6 +1572,7 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
745
1572
|
readonly websiteUrl?: string | undefined
|
|
746
1573
|
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
747
1574
|
readonly extensions?: ServerExtensions | undefined
|
|
1575
|
+
readonly cacheHints?: McpProtocolInternal.CacheHints | undefined
|
|
748
1576
|
readonly allowSubscriptions?: boolean | undefined
|
|
749
1577
|
},
|
|
750
1578
|
runtime: McpRuntime.ServerRuntimeShape,
|
|
@@ -770,11 +1598,19 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
770
1598
|
clientStates.delete(clientId)
|
|
771
1599
|
runtime.disconnect(clientId)
|
|
772
1600
|
}
|
|
773
|
-
|
|
1601
|
+
// The exit is sent already encoded, so it must carry only the JSON-RPC error members.
|
|
1602
|
+
const sendRequestError = (
|
|
1603
|
+
clientId: number,
|
|
1604
|
+
requestId: string | number,
|
|
1605
|
+
{ code, data, message }: { readonly code: number; readonly message: string; readonly data?: unknown }
|
|
1606
|
+
) =>
|
|
774
1607
|
protocol.send(clientId, {
|
|
775
1608
|
_tag: "Exit",
|
|
776
1609
|
requestId,
|
|
777
|
-
exit: {
|
|
1610
|
+
exit: {
|
|
1611
|
+
_tag: "Failure",
|
|
1612
|
+
cause: [{ _tag: "Fail", error: data === undefined ? { code, message } : { code, message, data } }]
|
|
1613
|
+
}
|
|
778
1614
|
})
|
|
779
1615
|
const removeReverseRequestClient = (requestId: string, key: McpClientKey) => {
|
|
780
1616
|
const waiting = reverseRequestClients.get(requestId)
|
|
@@ -1000,16 +1836,9 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
1000
1836
|
response.exit._tag === "Failure" &&
|
|
1001
1837
|
!response.exit.cause.some((failure) => failure._tag === "Fail")
|
|
1002
1838
|
) {
|
|
1003
|
-
return
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
exit: {
|
|
1007
|
-
_tag: "Failure",
|
|
1008
|
-
cause: [{
|
|
1009
|
-
_tag: "Fail",
|
|
1010
|
-
error: new InternalError({ message: "Internal error" })
|
|
1011
|
-
}]
|
|
1012
|
-
}
|
|
1839
|
+
return sendRequestError(clientId, response.requestId, {
|
|
1840
|
+
code: McpSchema.INTERNAL_ERROR_CODE,
|
|
1841
|
+
message: "Internal error"
|
|
1013
1842
|
})
|
|
1014
1843
|
}
|
|
1015
1844
|
}
|
|
@@ -1364,7 +2193,8 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
1364
2193
|
(requestContext?.clientId === clientId ? requestHeaders : undefined) ??
|
|
1365
2194
|
clientStates.get(clientId)?.sessionHeaders ?? Headers.empty,
|
|
1366
2195
|
notification,
|
|
1367
|
-
defaultLogLevel
|
|
2196
|
+
defaultLogLevel,
|
|
2197
|
+
listChangeRevision
|
|
1368
2198
|
)
|
|
1369
2199
|
) {
|
|
1370
2200
|
return
|
|
@@ -1411,6 +2241,37 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
1411
2241
|
)
|
|
1412
2242
|
}, Effect.scoped)
|
|
1413
2243
|
|
|
2244
|
+
type StatefulProtocolAdapter = McpProtocol.ProtocolAdapter<
|
|
2245
|
+
McpProtocol.ProtocolVersion,
|
|
2246
|
+
McpProtocol.StatefulRuntimeDescriptor
|
|
2247
|
+
>
|
|
2248
|
+
|
|
2249
|
+
/**
|
|
2250
|
+
* Request-level services supplied by a transport.
|
|
2251
|
+
*
|
|
2252
|
+
* **Details**
|
|
2253
|
+
*
|
|
2254
|
+
* Every transport supplies `Scope`. `McpServerClient` is supplied only when
|
|
2255
|
+
* every configured protocol is known to be sessionful: a `v2026_07_28` request
|
|
2256
|
+
* has no client session, and a protocol array widened to `ProtocolAdapter`
|
|
2257
|
+
* might contain one. HTTP transports also supply `HttpServerRequest`.
|
|
2258
|
+
*
|
|
2259
|
+
* @stability unstable
|
|
2260
|
+
* @category utility types
|
|
2261
|
+
* @since 4.0.0
|
|
2262
|
+
*/
|
|
2263
|
+
export type ProvidedServices<
|
|
2264
|
+
Protocols extends ReadonlyArray<McpProtocol.ProtocolAdapter>,
|
|
2265
|
+
Http extends boolean = false
|
|
2266
|
+
> =
|
|
2267
|
+
| Scope.Scope
|
|
2268
|
+
| (Protocols[number] extends StatefulProtocolAdapter ? McpServerClient : never)
|
|
2269
|
+
| (Http extends true ? HttpServerRequest.HttpServerRequest : never)
|
|
2270
|
+
|
|
2271
|
+
type RemainingRequestServices<RR, Provided> = Exclude<McpRequest.Only<"Requires", RR>, Provided>
|
|
2272
|
+
|
|
2273
|
+
type RegistrationServices<RR> = Exclude<McpRequest.Without<RR>, McpServer>
|
|
2274
|
+
|
|
1414
2275
|
/**
|
|
1415
2276
|
* Creates a layer that starts an MCP server over an existing
|
|
1416
2277
|
* `RpcServer.Protocol` and provides `McpServer`. Request handlers receive
|
|
@@ -1429,6 +2290,11 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
1429
2290
|
* `McpServer.layer`, so registration layers can use the `McpServer` service
|
|
1430
2291
|
* while the server is running.
|
|
1431
2292
|
*
|
|
2293
|
+
* Pass registration layers as `registrations` to build them before the server
|
|
2294
|
+
* reads its first request. The transport discharges the request-level
|
|
2295
|
+
* dependencies it supplies (see `ProvidedServices`); any other `McpRequest`
|
|
2296
|
+
* marker stays in the layer's requirements and must be met by MCP middleware.
|
|
2297
|
+
*
|
|
1432
2298
|
* **Gotchas**
|
|
1433
2299
|
*
|
|
1434
2300
|
* Unlike `layerStdio` and `layerHttp`, this layer does not install a concrete
|
|
@@ -1442,19 +2308,32 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
1442
2308
|
* @category layers
|
|
1443
2309
|
* @since 4.0.0
|
|
1444
2310
|
*/
|
|
1445
|
-
export const layer =
|
|
2311
|
+
export const layer = <
|
|
2312
|
+
const Protocols extends Arr.NonEmptyReadonlyArray<McpProtocol.ProtocolAdapter>,
|
|
2313
|
+
RA = never,
|
|
2314
|
+
RE = never,
|
|
2315
|
+
RR = never
|
|
2316
|
+
>(options: {
|
|
1446
2317
|
readonly name: string
|
|
1447
2318
|
readonly version: string
|
|
1448
2319
|
readonly instructions?: string | undefined
|
|
1449
2320
|
readonly description?: string | undefined
|
|
1450
2321
|
readonly websiteUrl?: string | undefined
|
|
1451
2322
|
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
1452
|
-
readonly protocols:
|
|
2323
|
+
readonly protocols: Protocols
|
|
1453
2324
|
readonly extensions?: ServerExtensions | undefined
|
|
1454
|
-
|
|
2325
|
+
readonly cacheHints?: CacheHints | undefined
|
|
2326
|
+
readonly registrations?: Layer.Layer<RA, RE, RR> | undefined
|
|
2327
|
+
}): Layer.Layer<
|
|
2328
|
+
McpServer | McpRequest.From<"Requires", ProvidedServices<Protocols>>,
|
|
2329
|
+
Cause.IllegalArgumentError | RE,
|
|
2330
|
+
| RpcServer.Protocol
|
|
2331
|
+
| RegistrationServices<RR>
|
|
2332
|
+
| McpRequest.From<"Requires", RemainingRequestServices<RR, ProvidedServices<Protocols>>>
|
|
2333
|
+
> =>
|
|
1455
2334
|
layerWithRuntime(options, "custom").pipe(
|
|
1456
2335
|
Layer.provide(McpRuntime.layer(options.protocols))
|
|
1457
|
-
)
|
|
2336
|
+
) as any
|
|
1458
2337
|
|
|
1459
2338
|
const layerWithRuntime = (options: {
|
|
1460
2339
|
readonly name: string
|
|
@@ -1464,18 +2343,18 @@ const layerWithRuntime = (options: {
|
|
|
1464
2343
|
readonly websiteUrl?: string | undefined
|
|
1465
2344
|
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
1466
2345
|
readonly extensions?: ServerExtensions | undefined
|
|
2346
|
+
readonly cacheHints?: CacheHints | undefined
|
|
1467
2347
|
readonly allowSubscriptions?: boolean | undefined
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
never,
|
|
1471
|
-
RpcServer.Protocol | McpRuntime.ServerRuntime
|
|
1472
|
-
> =>
|
|
2348
|
+
readonly registrations?: Layer.Layer<any, any, any> | undefined
|
|
2349
|
+
}, transport: "custom" | "http" | "stdio") =>
|
|
1473
2350
|
Layer.effectDiscard(
|
|
1474
2351
|
Effect.gen(function*() {
|
|
2352
|
+
const cacheHints = yield* normalizeCacheHints(options.cacheHints)
|
|
1475
2353
|
const runtime = yield* McpRuntime.ServerRuntime
|
|
1476
|
-
yield* Effect.forkScoped(runWithRuntime(options, runtime, transport))
|
|
2354
|
+
yield* Effect.forkScoped(runWithRuntime({ ...options, cacheHints }, runtime, transport))
|
|
1477
2355
|
})
|
|
1478
2356
|
).pipe(
|
|
2357
|
+
Layer.provide(options.registrations ?? Layer.empty),
|
|
1479
2358
|
Layer.provideMerge(McpServer.layer)
|
|
1480
2359
|
)
|
|
1481
2360
|
|
|
@@ -1494,6 +2373,11 @@ const layerWithRuntime = (options: {
|
|
|
1494
2373
|
* `McpRequestContext` and legacy `McpServerClient` services to handlers, and
|
|
1495
2374
|
* requires `Stdio`.
|
|
1496
2375
|
*
|
|
2376
|
+
* Pass registration layers as `registrations` to build them before the server
|
|
2377
|
+
* reads its first request. The transport discharges the request-level
|
|
2378
|
+
* dependencies it supplies (see `ProvidedServices`); any other `McpRequest`
|
|
2379
|
+
* marker stays in the layer's requirements and must be met by MCP middleware.
|
|
2380
|
+
*
|
|
1497
2381
|
* @see {@link layer} for running over an existing `RpcServer.Protocol`
|
|
1498
2382
|
* @see {@link layerHttp} for the single-endpoint HTTP transport
|
|
1499
2383
|
*
|
|
@@ -1501,16 +2385,29 @@ const layerWithRuntime = (options: {
|
|
|
1501
2385
|
* @category layers
|
|
1502
2386
|
* @since 4.0.0
|
|
1503
2387
|
*/
|
|
1504
|
-
export const layerStdio =
|
|
2388
|
+
export const layerStdio = <
|
|
2389
|
+
const Protocols extends Arr.NonEmptyReadonlyArray<McpProtocol.ProtocolAdapter>,
|
|
2390
|
+
RA = never,
|
|
2391
|
+
RE = never,
|
|
2392
|
+
RR = never
|
|
2393
|
+
>(options: {
|
|
1505
2394
|
readonly name: string
|
|
1506
2395
|
readonly version: string
|
|
1507
2396
|
readonly instructions?: string | undefined
|
|
1508
2397
|
readonly description?: string | undefined
|
|
1509
2398
|
readonly websiteUrl?: string | undefined
|
|
1510
2399
|
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
1511
|
-
readonly protocols:
|
|
2400
|
+
readonly protocols: Protocols
|
|
1512
2401
|
readonly extensions?: ServerExtensions | undefined
|
|
1513
|
-
|
|
2402
|
+
readonly cacheHints?: CacheHints | undefined
|
|
2403
|
+
readonly registrations?: Layer.Layer<RA, RE, RR> | undefined
|
|
2404
|
+
}): Layer.Layer<
|
|
2405
|
+
McpServer | McpRequest.From<"Requires", ProvidedServices<Protocols>>,
|
|
2406
|
+
Cause.IllegalArgumentError | RE,
|
|
2407
|
+
| Stdio
|
|
2408
|
+
| RegistrationServices<RR>
|
|
2409
|
+
| McpRequest.From<"Requires", RemainingRequestServices<RR, ProvidedServices<Protocols>>>
|
|
2410
|
+
> =>
|
|
1514
2411
|
layerWithRuntime(options, "stdio").pipe(
|
|
1515
2412
|
Layer.provide(McpRuntime.layer(options.protocols)),
|
|
1516
2413
|
Layer.provide(RpcServer.layerProtocolStdio),
|
|
@@ -1518,7 +2415,7 @@ export const layerStdio = (options: {
|
|
|
1518
2415
|
RpcSerialization.RpcSerialization,
|
|
1519
2416
|
mcpStdioSerialization(options.protocols)
|
|
1520
2417
|
))
|
|
1521
|
-
)
|
|
2418
|
+
) as any
|
|
1522
2419
|
|
|
1523
2420
|
const mcpStdioSerialization = (
|
|
1524
2421
|
protocols: Arr.NonEmptyReadonlyArray<McpProtocol.ProtocolAdapter>
|
|
@@ -1620,6 +2517,13 @@ const mcpStdioSerialization = (
|
|
|
1620
2517
|
* serverless hosts where execution must belong to each request, use
|
|
1621
2518
|
* `layerHttpRequestScoped` instead.
|
|
1622
2519
|
*
|
|
2520
|
+
* Pass registration layers as `registrations` to build them before the
|
|
2521
|
+
* endpoint serves its first request. The transport discharges the
|
|
2522
|
+
* request-level dependencies it supplies (see `ProvidedServices`) and converts
|
|
2523
|
+
* the remaining `McpRequest` markers into `HttpRouter.Request` markers, so
|
|
2524
|
+
* `HttpRouter.middleware` can provide them, for example to authenticate the
|
|
2525
|
+
* request and resolve the current user.
|
|
2526
|
+
*
|
|
1623
2527
|
* `layerHttp` always implements the single-endpoint Streamable HTTP topology.
|
|
1624
2528
|
* Using `v2024_11_05` here is a custom compatibility transport for that
|
|
1625
2529
|
* revision's schema. It does not implement the historical two-endpoint
|
|
@@ -1637,7 +2541,12 @@ const mcpStdioSerialization = (
|
|
|
1637
2541
|
* @category layers
|
|
1638
2542
|
* @since 4.0.0
|
|
1639
2543
|
*/
|
|
1640
|
-
export const layerHttp =
|
|
2544
|
+
export const layerHttp = <
|
|
2545
|
+
const Protocols extends Arr.NonEmptyReadonlyArray<McpProtocol.ProtocolAdapter>,
|
|
2546
|
+
RA = never,
|
|
2547
|
+
RE = never,
|
|
2548
|
+
RR = never
|
|
2549
|
+
>(options: {
|
|
1641
2550
|
readonly name: string
|
|
1642
2551
|
readonly version: string
|
|
1643
2552
|
readonly instructions?: string | undefined
|
|
@@ -1645,18 +2554,26 @@ export const layerHttp = (options: {
|
|
|
1645
2554
|
readonly websiteUrl?: string | undefined
|
|
1646
2555
|
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
1647
2556
|
readonly path: HttpRouter.PathInput
|
|
1648
|
-
readonly protocols:
|
|
2557
|
+
readonly protocols: Protocols
|
|
1649
2558
|
readonly extensions?: ServerExtensions | undefined
|
|
2559
|
+
readonly cacheHints?: CacheHints | undefined
|
|
1650
2560
|
readonly allowedOrigins?: ReadonlyArray<string> | undefined
|
|
1651
2561
|
readonly allowSessionTermination?: boolean | undefined
|
|
1652
2562
|
readonly allowSubscriptions?: boolean | undefined
|
|
1653
|
-
|
|
2563
|
+
readonly registrations?: Layer.Layer<RA, RE, RR> | undefined
|
|
2564
|
+
}): Layer.Layer<
|
|
2565
|
+
McpServer | McpRequest.From<"Requires", ProvidedServices<Protocols, true>>,
|
|
2566
|
+
Cause.IllegalArgumentError | RE,
|
|
2567
|
+
| HttpRouter.HttpRouter
|
|
2568
|
+
| RegistrationServices<RR>
|
|
2569
|
+
| HttpRouter.Request.From<"Requires", RemainingRequestServices<RR, ProvidedServices<Protocols, true>>>
|
|
2570
|
+
> => {
|
|
1654
2571
|
const runtime = McpRuntime.layer(options.protocols)
|
|
1655
2572
|
return layerWithRuntime(options, "http").pipe(
|
|
1656
2573
|
Layer.provide(layerMcpProtocolHttp(options)),
|
|
1657
2574
|
Layer.provide(runtime),
|
|
1658
2575
|
Layer.provide(RpcSerialization.layerJsonRpc())
|
|
1659
|
-
)
|
|
2576
|
+
) as any
|
|
1660
2577
|
}
|
|
1661
2578
|
|
|
1662
2579
|
/**
|
|
@@ -1687,13 +2604,24 @@ export const layerHttp = (options: {
|
|
|
1687
2604
|
* Configuring a sessionful protocol through an untyped caller fails layer
|
|
1688
2605
|
* construction with `IllegalArgumentError`.
|
|
1689
2606
|
*
|
|
2607
|
+
* Registrations passed as `registrations` are built once, before the routes
|
|
2608
|
+
* are added, and shared by every POST. Remaining `McpRequest` markers become
|
|
2609
|
+
* `HttpRouter.Request` markers, as with `layerHttp`.
|
|
2610
|
+
*
|
|
1690
2611
|
* @see {@link layerHttp} for the long-lived HTTP transport and HTTP admission policy
|
|
1691
2612
|
*
|
|
1692
2613
|
* @stability unstable
|
|
1693
2614
|
* @category layers
|
|
1694
2615
|
* @since 4.0.0
|
|
1695
2616
|
*/
|
|
1696
|
-
export const layerHttpRequestScoped =
|
|
2617
|
+
export const layerHttpRequestScoped = <
|
|
2618
|
+
const Protocols extends Arr.NonEmptyReadonlyArray<
|
|
2619
|
+
McpProtocol.ProtocolAdapter<McpProtocol.ProtocolVersion, McpProtocol.StatelessRuntimeDescriptor>
|
|
2620
|
+
>,
|
|
2621
|
+
RA = never,
|
|
2622
|
+
RE = never,
|
|
2623
|
+
RR = never
|
|
2624
|
+
>(options: {
|
|
1697
2625
|
readonly name: string
|
|
1698
2626
|
readonly version: string
|
|
1699
2627
|
readonly instructions?: string | undefined
|
|
@@ -1701,12 +2629,18 @@ export const layerHttpRequestScoped = (options: {
|
|
|
1701
2629
|
readonly websiteUrl?: string | undefined
|
|
1702
2630
|
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
1703
2631
|
readonly path: HttpRouter.PathInput
|
|
1704
|
-
readonly protocols:
|
|
1705
|
-
McpProtocol.ProtocolAdapter<McpProtocol.ProtocolVersion, McpProtocol.StatelessRuntimeDescriptor>
|
|
1706
|
-
>
|
|
2632
|
+
readonly protocols: Protocols
|
|
1707
2633
|
readonly extensions?: ServerExtensions | undefined
|
|
2634
|
+
readonly cacheHints?: CacheHints | undefined
|
|
1708
2635
|
readonly allowedOrigins?: ReadonlyArray<string> | undefined
|
|
1709
|
-
|
|
2636
|
+
readonly registrations?: Layer.Layer<RA, RE, RR> | undefined
|
|
2637
|
+
}): Layer.Layer<
|
|
2638
|
+
McpServer | McpRequest.From<"Requires", ProvidedServices<Protocols, true>>,
|
|
2639
|
+
Cause.IllegalArgumentError | RE,
|
|
2640
|
+
| HttpRouter.HttpRouter
|
|
2641
|
+
| RegistrationServices<RR>
|
|
2642
|
+
| HttpRouter.Request.From<"Requires", RemainingRequestServices<RR, ProvidedServices<Protocols, true>>>
|
|
2643
|
+
> =>
|
|
1710
2644
|
Layer.effectDiscard(Effect.gen(function*() {
|
|
1711
2645
|
const runtime = yield* McpRuntime.ServerRuntime
|
|
1712
2646
|
const stateful = runtime.protocols.find((protocol) => protocol.runtime._tag === "Stateful")
|
|
@@ -1715,6 +2649,7 @@ export const layerHttpRequestScoped = (options: {
|
|
|
1715
2649
|
`McpServer.layerHttpRequestScoped does not support the sessionful MCP protocol ${stateful.protocolVersion}`
|
|
1716
2650
|
)
|
|
1717
2651
|
}
|
|
2652
|
+
const serverOptions = { ...options, cacheHints: yield* normalizeCacheHints(options.cacheHints) }
|
|
1718
2653
|
const server = yield* McpServer
|
|
1719
2654
|
const { core, notificationDelivery } = internalState.get(server)!
|
|
1720
2655
|
// Subscriptions are disabled, so handlers hold no per-request state and
|
|
@@ -1725,7 +2660,7 @@ export const layerHttpRequestScoped = (options: {
|
|
|
1725
2660
|
subscribeServerNotifications: Effect.die("Subscriptions are disabled for request-scoped MCP servers"),
|
|
1726
2661
|
getListChangeRevision: () => notificationDelivery.listChangeRevision,
|
|
1727
2662
|
defaultLogLevel: yield* CurrentLogLevel,
|
|
1728
|
-
serverInfo:
|
|
2663
|
+
serverInfo: serverOptions
|
|
1729
2664
|
}) as Effect.Effect<Context.Context<never>>)
|
|
1730
2665
|
yield* Effect.acquireRelease(
|
|
1731
2666
|
Effect.sync(() => {
|
|
@@ -1745,7 +2680,7 @@ export const layerHttpRequestScoped = (options: {
|
|
|
1745
2680
|
Effect.provideService(RpcSerialization.RpcSerialization, mcpHttpSerialization)
|
|
1746
2681
|
)
|
|
1747
2682
|
const notifications = yield* Queue.make<QueuedServerNotification>()
|
|
1748
|
-
yield* runWithRuntime(
|
|
2683
|
+
yield* runWithRuntime(serverOptions, runtime, "http", { notifications, handlers }).pipe(
|
|
1749
2684
|
Effect.provideService(RpcServer.Protocol, protocol),
|
|
1750
2685
|
Effect.provideService(McpServer, server),
|
|
1751
2686
|
Effect.forkScoped({ startImmediately: true })
|
|
@@ -1754,9 +2689,10 @@ export const layerHttpRequestScoped = (options: {
|
|
|
1754
2689
|
})
|
|
1755
2690
|
)
|
|
1756
2691
|
})).pipe(
|
|
2692
|
+
Layer.provide(options.registrations ?? Layer.empty),
|
|
1757
2693
|
Layer.provideMerge(McpServer.layer),
|
|
1758
2694
|
Layer.provide(McpRuntime.layer(options.protocols))
|
|
1759
|
-
)
|
|
2695
|
+
) as any
|
|
1760
2696
|
|
|
1761
2697
|
const layerMcpProtocolHttp = (options: {
|
|
1762
2698
|
readonly path: HttpRouter.PathInput
|
|
@@ -1900,7 +2836,7 @@ const normalizeMcpJsonRpcResponse = (response: unknown): unknown => {
|
|
|
1900
2836
|
function mcpJsonRpcSerialization(options?: {
|
|
1901
2837
|
readonly contentType?: string | undefined
|
|
1902
2838
|
}): RpcSerialization.RpcSerialization["Service"] {
|
|
1903
|
-
const serialization = RpcSerialization.jsonRpc(options)
|
|
2839
|
+
const serialization = RpcSerialization.jsonRpc({ ...options, controlMessages: false })
|
|
1904
2840
|
return RpcSerialization.RpcSerialization.of({
|
|
1905
2841
|
...serialization,
|
|
1906
2842
|
makeUnsafe: () => {
|
|
@@ -2025,20 +2961,50 @@ const toolErrorResult = (message: string): CallToolResult =>
|
|
|
2025
2961
|
const toolResultContent = (encoded: unknown): CallToolResult["content"] =>
|
|
2026
2962
|
encoded === undefined ? [] : [{ type: "text", text: JSON.stringify(encoded) }]
|
|
2027
2963
|
|
|
2964
|
+
/**
|
|
2965
|
+
* The requirements of a toolkit registration.
|
|
2966
|
+
*
|
|
2967
|
+
* **Details**
|
|
2968
|
+
*
|
|
2969
|
+
* Services a tool declares with `dependencies` or `Tool.addDependency` are
|
|
2970
|
+
* request-level: they are carried as `McpRequest<"Requires", S>` markers and
|
|
2971
|
+
* must be provided by MCP middleware or the transport. Parameter decoding and
|
|
2972
|
+
* result encoding services are required when the toolkit is registered,
|
|
2973
|
+
* unless a tool also declares them.
|
|
2974
|
+
*
|
|
2975
|
+
* @stability unstable
|
|
2976
|
+
* @category utility types
|
|
2977
|
+
* @since 4.0.0
|
|
2978
|
+
*/
|
|
2979
|
+
export type ToolkitRequirements<Tools extends Record<string, Tool.Any>> = 0 extends
|
|
2980
|
+
(1 & Tool.Requirements<Tools[keyof Tools]>) ? any :
|
|
2981
|
+
| Tool.HandlersFor<Tools>
|
|
2982
|
+
| RegistrationRequirements<Tool.SchemaServices<Tools[keyof Tools]>, Tool.Requirements<Tools[keyof Tools]>>
|
|
2983
|
+
|
|
2984
|
+
type RegistrationRequirements<SchemaServices, RequestServices> =
|
|
2985
|
+
| McpServer
|
|
2986
|
+
| Exclude<SchemaServices, RequestServices | McpRequestContext>
|
|
2987
|
+
| McpRequest.From<"Requires", Exclude<RequestServices, McpRequestContext>>
|
|
2988
|
+
|
|
2028
2989
|
/**
|
|
2029
2990
|
* Registers a `Toolkit` with the `McpServer`.
|
|
2030
2991
|
*
|
|
2992
|
+
* **Details**
|
|
2993
|
+
*
|
|
2994
|
+
* The MCP middleware in the current context, provided with
|
|
2995
|
+
* `Effect.provide(middleware.layer)`, runs around every call to the toolkit.
|
|
2996
|
+
*
|
|
2997
|
+
* @see {@link ToolkitRequirements} for which services are request-level
|
|
2998
|
+
*
|
|
2031
2999
|
* @stability unstable
|
|
2032
3000
|
* @category handlers
|
|
2033
3001
|
* @since 4.0.0
|
|
2034
3002
|
*/
|
|
2035
3003
|
export const registerToolkit: <Tools extends Record<string, Tool.Any>>(
|
|
2036
3004
|
toolkit: Toolkit.Toolkit<Tools>
|
|
2037
|
-
) => Effect.Effect<
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
McpServer | Tool.HandlersFor<Tools> | Exclude<Tool.HandlerServices<Tools[keyof Tools]>, McpRequestContext>
|
|
2041
|
-
> = Effect.fnUntraced(function*<Tools extends Record<string, Tool.Any>>(
|
|
3005
|
+
) => Effect.Effect<void, never, ToolkitRequirements<Tools>> = Effect.fnUntraced(function*<
|
|
3006
|
+
Tools extends Record<string, Tool.Any>
|
|
3007
|
+
>(
|
|
2042
3008
|
toolkit: Toolkit.Toolkit<Tools>
|
|
2043
3009
|
) {
|
|
2044
3010
|
const registry = yield* McpServer
|
|
@@ -2057,19 +3023,14 @@ export const registerToolkit: <Tools extends Record<string, Tool.Any>>(
|
|
|
2057
3023
|
}
|
|
2058
3024
|
return Context.makeUnsafe(services)
|
|
2059
3025
|
}))
|
|
2060
|
-
const services =
|
|
2061
|
-
yield* Effect.context<
|
|
2062
|
-
Exclude<Tool.HandlerServices<Tools[keyof Tools]>, McpRequestContext>
|
|
2063
|
-
>()
|
|
2064
|
-
)
|
|
2065
|
-
const reportCause = (cause: Cause.Cause<unknown>) => Effect.provideContext(ErrorReporter.report(cause), services)
|
|
3026
|
+
const services = yield* Effect.context<never>()
|
|
2066
3027
|
// Interruption propagates; anything else is logged, reported and scrubbed.
|
|
2067
3028
|
const internalToolError = (cause: Cause.Cause<unknown>) => {
|
|
2068
3029
|
const failure = Cause.findFail(cause)
|
|
2069
3030
|
return Result.isFailure(failure) && !Cause.hasDies(cause)
|
|
2070
3031
|
? Effect.failCause(failure.failure)
|
|
2071
3032
|
: Effect.logError(cause).pipe(
|
|
2072
|
-
Effect.andThen(
|
|
3033
|
+
Effect.andThen(ErrorReporter.report(cause)),
|
|
2073
3034
|
Effect.as(toolErrorResult(INTERNAL_TOOL_ERROR_MESSAGE))
|
|
2074
3035
|
)
|
|
2075
3036
|
}
|
|
@@ -2167,10 +3128,10 @@ export const registerToolkit: <Tools extends Record<string, Tool.Any>>(
|
|
|
2167
3128
|
})
|
|
2168
3129
|
)
|
|
2169
3130
|
),
|
|
2170
|
-
Effect.catchCause(handleCause)
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
3131
|
+
Effect.catchCause(handleCause)
|
|
3132
|
+
) as Effect.Effect<CallToolResult, InvalidParams, never>
|
|
3133
|
+
},
|
|
3134
|
+
services
|
|
2174
3135
|
})
|
|
2175
3136
|
}
|
|
2176
3137
|
for (const registration of registrations) {
|
|
@@ -2200,7 +3161,14 @@ const toolJsonSchema = (schema: Schema.Constraint, strict: boolean): JsonSchema.
|
|
|
2200
3161
|
}
|
|
2201
3162
|
|
|
2202
3163
|
/**
|
|
2203
|
-
*
|
|
3164
|
+
* Creates a layer that registers a `Toolkit` with the `McpServer`.
|
|
3165
|
+
*
|
|
3166
|
+
* **Details**
|
|
3167
|
+
*
|
|
3168
|
+
* The layer requires `McpServer`. Pass it to a transport through the
|
|
3169
|
+
* `registrations` option, or provide the transport layer to it.
|
|
3170
|
+
*
|
|
3171
|
+
* @see {@link ToolkitRequirements} for which services are request-level
|
|
2204
3172
|
*
|
|
2205
3173
|
* @stability unstable
|
|
2206
3174
|
* @category layers
|
|
@@ -2208,14 +3176,7 @@ const toolJsonSchema = (schema: Schema.Constraint, strict: boolean): JsonSchema.
|
|
|
2208
3176
|
*/
|
|
2209
3177
|
export const toolkit = <Tools extends Record<string, Tool.Any>>(
|
|
2210
3178
|
toolkit: Toolkit.Toolkit<Tools>
|
|
2211
|
-
): Layer.Layer<
|
|
2212
|
-
never,
|
|
2213
|
-
never,
|
|
2214
|
-
Tool.HandlersFor<Tools> | Exclude<Tool.HandlerServices<Tools[keyof Tools]>, McpRequestContext>
|
|
2215
|
-
> =>
|
|
2216
|
-
Layer.effectDiscard(registerToolkit(toolkit)).pipe(
|
|
2217
|
-
Layer.provide(McpServer.layer)
|
|
2218
|
-
)
|
|
3179
|
+
): Layer.Layer<never, never, ToolkitRequirements<Tools>> => Layer.effectDiscard(registerToolkit(toolkit))
|
|
2219
3180
|
|
|
2220
3181
|
/**
|
|
2221
3182
|
* Utility type that validates a completion-handler record against the allowed
|
|
@@ -2271,6 +3232,90 @@ export type ResourceCompletions<Schemas extends ReadonlyArray<Schema.Constraint>
|
|
|
2271
3232
|
) => Effect.Effect<Array<Schemas[K]["Type"]>, any, any>
|
|
2272
3233
|
}
|
|
2273
3234
|
|
|
3235
|
+
// Leave defects and interruption to makeInvoke; convert only expected failures.
|
|
3236
|
+
const handlerFailureToInternalError = (cause: Cause.Cause<unknown>): Effect.Effect<never, InternalError> =>
|
|
3237
|
+
Cause.hasDies(cause) || Cause.hasInterrupts(cause)
|
|
3238
|
+
? Effect.failCause(cause as Cause.Cause<never>)
|
|
3239
|
+
: Effect.fail(new InternalError({ message: Cause.prettyErrors(cause)[0].message }))
|
|
3240
|
+
|
|
3241
|
+
const completionHandler = (
|
|
3242
|
+
handle: (input: string, context: CompletionContext) => Effect.Effect<any, any, any>,
|
|
3243
|
+
encodeValues: (values: unknown) => Effect.Effect<ReadonlyArray<unknown>, any, any>
|
|
3244
|
+
) =>
|
|
3245
|
+
(input: string, context: CompletionContext): Effect.Effect<CompleteResult, InternalError> =>
|
|
3246
|
+
handle(input, context).pipe(
|
|
3247
|
+
Effect.flatMap(encodeValues),
|
|
3248
|
+
Effect.map((values) => ({
|
|
3249
|
+
completion: {
|
|
3250
|
+
values: values as Array<string>,
|
|
3251
|
+
total: values.length,
|
|
3252
|
+
hasMore: false
|
|
3253
|
+
}
|
|
3254
|
+
})),
|
|
3255
|
+
Effect.catchCause(handlerFailureToInternalError)
|
|
3256
|
+
) as any
|
|
3257
|
+
|
|
3258
|
+
type TemplateParamKey<Schemas extends ReadonlyArray<Schema.Constraint>, K extends keyof Schemas> = Schemas[K] extends
|
|
3259
|
+
Param<infer Id, infer _S> ? Id : `param${K & string}`
|
|
3260
|
+
|
|
3261
|
+
type TemplateSchemaServices<Schemas extends ReadonlyArray<Schema.Constraint>, Completions> =
|
|
3262
|
+
| Schemas[number]["DecodingServices"]
|
|
3263
|
+
| {
|
|
3264
|
+
[K in Extract<keyof Schemas, `${number}`>]: TemplateParamKey<Schemas, K> extends keyof Completions
|
|
3265
|
+
? Schemas[K]["EncodingServices"]
|
|
3266
|
+
: never
|
|
3267
|
+
}[Extract<keyof Schemas, `${number}`>]
|
|
3268
|
+
|
|
3269
|
+
type PromptSchemaServices<Params extends Schema.Struct.Fields, Completions> =
|
|
3270
|
+
| Schema.Struct.DecodingServices<Params>
|
|
3271
|
+
| Params[Extract<keyof Completions, keyof Params>]["EncodingServices"]
|
|
3272
|
+
|
|
3273
|
+
/**
|
|
3274
|
+
* The requirements of a resource registration: the content handler's services
|
|
3275
|
+
* are request-level.
|
|
3276
|
+
*
|
|
3277
|
+
* @stability unstable
|
|
3278
|
+
* @category utility types
|
|
3279
|
+
* @since 4.0.0
|
|
3280
|
+
*/
|
|
3281
|
+
export type ResourceRequirements<R> = RegistrationRequirements<never, R>
|
|
3282
|
+
|
|
3283
|
+
/**
|
|
3284
|
+
* The requirements of a resource template registration.
|
|
3285
|
+
*
|
|
3286
|
+
* **Details**
|
|
3287
|
+
*
|
|
3288
|
+
* Services read by the content and completion handlers are request-level.
|
|
3289
|
+
* Parameter decoding services, and the encoding services of parameters with a
|
|
3290
|
+
* completion handler, are required when the template is registered, unless a
|
|
3291
|
+
* handler also reads them.
|
|
3292
|
+
*
|
|
3293
|
+
* @stability unstable
|
|
3294
|
+
* @category utility types
|
|
3295
|
+
* @since 4.0.0
|
|
3296
|
+
*/
|
|
3297
|
+
export type ResourceTemplateRequirements<Schemas extends ReadonlyArray<Schema.Constraint>, R, Completions> =
|
|
3298
|
+
RegistrationRequirements<TemplateSchemaServices<Schemas, Completions>, R | CompletionServices<Completions>>
|
|
3299
|
+
|
|
3300
|
+
/**
|
|
3301
|
+
* The requirements of a prompt registration.
|
|
3302
|
+
*
|
|
3303
|
+
* **Details**
|
|
3304
|
+
*
|
|
3305
|
+
* Services read by the content and completion handlers are request-level.
|
|
3306
|
+
* Parameter decoding services, and the encoding services of parameters with a
|
|
3307
|
+
* completion handler, are required when the prompt is registered, unless a
|
|
3308
|
+
* handler also reads them.
|
|
3309
|
+
*
|
|
3310
|
+
* @stability unstable
|
|
3311
|
+
* @category utility types
|
|
3312
|
+
* @since 4.0.0
|
|
3313
|
+
*/
|
|
3314
|
+
export type PromptRequirements<Params extends Schema.Struct.Fields, R, Completions> = RegistrationRequirements<
|
|
3315
|
+
PromptSchemaServices<Params, Completions>,
|
|
3316
|
+
R | CompletionServices<Completions>
|
|
3317
|
+
>
|
|
3318
|
+
|
|
2274
3319
|
/**
|
|
2275
3320
|
* Registers an MCP resource or resource template from an Effect program.
|
|
2276
3321
|
*
|
|
@@ -2305,7 +3350,7 @@ export const registerResource: {
|
|
|
2305
3350
|
>
|
|
2306
3351
|
readonly annotations?: Context.Context<never> | undefined
|
|
2307
3352
|
}
|
|
2308
|
-
): Effect.Effect<void, never,
|
|
3353
|
+
): Effect.Effect<void, never, ResourceRequirements<R>>
|
|
2309
3354
|
/**
|
|
2310
3355
|
* Registers an MCP resource or resource template from an Effect program.
|
|
2311
3356
|
*
|
|
@@ -2332,18 +3377,7 @@ export const registerResource: {
|
|
|
2332
3377
|
R
|
|
2333
3378
|
>
|
|
2334
3379
|
readonly annotations?: Context.Context<never> | undefined
|
|
2335
|
-
}) => Effect.Effect<
|
|
2336
|
-
void,
|
|
2337
|
-
never,
|
|
2338
|
-
| Exclude<
|
|
2339
|
-
| Schemas[number]["DecodingServices"]
|
|
2340
|
-
| Schemas[number]["EncodingServices"]
|
|
2341
|
-
| R
|
|
2342
|
-
| CompletionServices<Completions>,
|
|
2343
|
-
McpRequestContext
|
|
2344
|
-
>
|
|
2345
|
-
| McpServer
|
|
2346
|
-
>
|
|
3380
|
+
}) => Effect.Effect<void, never, ResourceTemplateRequirements<Schemas, R, Completions>>
|
|
2347
3381
|
} = function() {
|
|
2348
3382
|
if (arguments.length === 1) {
|
|
2349
3383
|
const options = arguments[0] as {
|
|
@@ -2357,20 +3391,17 @@ export const registerResource: {
|
|
|
2357
3391
|
readonly annotations?: Context.Context<never> | undefined
|
|
2358
3392
|
}
|
|
2359
3393
|
return Effect.gen(function*() {
|
|
2360
|
-
const services =
|
|
3394
|
+
const services = yield* Effect.context<never>()
|
|
2361
3395
|
const registry = yield* McpServer
|
|
2362
3396
|
yield* registry.addResource({
|
|
2363
3397
|
resource: new Resource({
|
|
2364
3398
|
...options,
|
|
2365
3399
|
annotations: options
|
|
2366
3400
|
}),
|
|
3401
|
+
services,
|
|
2367
3402
|
handle: options.content.pipe(
|
|
2368
|
-
Effect.provideContext(services),
|
|
2369
3403
|
Effect.map((content) => resolveResourceContent(options.uri, content)),
|
|
2370
|
-
Effect.catchCause(
|
|
2371
|
-
const prettyError = Cause.prettyErrors(cause)[0]
|
|
2372
|
-
return Effect.fail(new InternalError({ message: prettyError.message }))
|
|
2373
|
-
})
|
|
3404
|
+
Effect.catchCause(handlerFailureToInternalError)
|
|
2374
3405
|
),
|
|
2375
3406
|
annotations: options.annotations ?? Context.empty()
|
|
2376
3407
|
})
|
|
@@ -2404,7 +3435,7 @@ export const registerResource: {
|
|
|
2404
3435
|
>
|
|
2405
3436
|
readonly annotations?: Context.Context<never> | undefined
|
|
2406
3437
|
}) {
|
|
2407
|
-
const services =
|
|
3438
|
+
const services = yield* Effect.context<never>()
|
|
2408
3439
|
const registry = yield* McpServer
|
|
2409
3440
|
const decode = Schema.decodeUnknownEffect(schema)
|
|
2410
3441
|
const template = new ResourceTemplate({
|
|
@@ -2420,32 +3451,13 @@ export const registerResource: {
|
|
|
2420
3451
|
) => Effect.Effect<CompleteResult, InternalError>
|
|
2421
3452
|
> = Object.create(null)
|
|
2422
3453
|
for (const [param, handle] of Object.entries(options.completion ?? {})) {
|
|
2423
|
-
|
|
2424
|
-
const handler = (
|
|
2425
|
-
input: string,
|
|
2426
|
-
context: CompletionContext
|
|
2427
|
-
) =>
|
|
2428
|
-
handle(input, context).pipe(
|
|
2429
|
-
Effect.flatMap(encodeArray),
|
|
2430
|
-
Effect.map((values) => ({
|
|
2431
|
-
completion: {
|
|
2432
|
-
values: values as Array<string>,
|
|
2433
|
-
total: values.length,
|
|
2434
|
-
hasMore: false
|
|
2435
|
-
}
|
|
2436
|
-
})),
|
|
2437
|
-
Effect.catchCause((cause) => {
|
|
2438
|
-
const prettyError = Cause.prettyErrors(cause)[0]
|
|
2439
|
-
return Effect.fail(new InternalError({ message: prettyError.message }))
|
|
2440
|
-
}),
|
|
2441
|
-
Effect.provideContext(services)
|
|
2442
|
-
)
|
|
2443
|
-
completions[param] = handler
|
|
3454
|
+
completions[param] = completionHandler(handle, Schema.encodeUnknownEffect(Schema.Array(params[param])))
|
|
2444
3455
|
}
|
|
2445
3456
|
yield* registry.addResourceTemplate({
|
|
2446
3457
|
template,
|
|
2447
3458
|
routerPath,
|
|
2448
3459
|
completions,
|
|
3460
|
+
services,
|
|
2449
3461
|
annotations: options.annotations ?? Context.empty(),
|
|
2450
3462
|
handle: (uri, params) =>
|
|
2451
3463
|
decode(params).pipe(
|
|
@@ -2453,14 +3465,10 @@ export const registerResource: {
|
|
|
2453
3465
|
Effect.flatMap((params: any) =>
|
|
2454
3466
|
options.content(uri, ...params).pipe(
|
|
2455
3467
|
Effect.map((content) => resolveResourceContent(uri, content)),
|
|
2456
|
-
Effect.catchCause(
|
|
2457
|
-
const prettyError = Cause.prettyErrors(cause)[0]
|
|
2458
|
-
return Effect.fail(new InternalError({ message: prettyError.message }))
|
|
2459
|
-
})
|
|
3468
|
+
Effect.catchCause(handlerFailureToInternalError)
|
|
2460
3469
|
)
|
|
2461
|
-
)
|
|
2462
|
-
|
|
2463
|
-
)
|
|
3470
|
+
)
|
|
3471
|
+
) as Effect.Effect<ReadResourceResult, InvalidParams | InternalError>
|
|
2464
3472
|
})
|
|
2465
3473
|
})
|
|
2466
3474
|
} as any
|
|
@@ -2468,7 +3476,15 @@ export const registerResource: {
|
|
|
2468
3476
|
/**
|
|
2469
3477
|
* Creates a layer that registers an MCP resource or resource template.
|
|
2470
3478
|
*
|
|
3479
|
+
* **Details**
|
|
3480
|
+
*
|
|
3481
|
+
* Services read by the content and completion handlers are request-level, so
|
|
3482
|
+
* providing them with `Layer.provide` doesn't satisfy them. Read
|
|
3483
|
+
* construction-time services in an enclosing `Layer.unwrap` and close over
|
|
3484
|
+
* them, and provide per-request services with MCP middleware.
|
|
3485
|
+
*
|
|
2471
3486
|
* @see {@link registerResource} for the Effect-level resource registration API
|
|
3487
|
+
* @see {@link middleware} for providing request-level dependencies
|
|
2472
3488
|
*
|
|
2473
3489
|
* @stability unstable
|
|
2474
3490
|
* @category layers
|
|
@@ -2478,7 +3494,15 @@ export const resource: {
|
|
|
2478
3494
|
/**
|
|
2479
3495
|
* Creates a layer that registers an MCP resource or resource template.
|
|
2480
3496
|
*
|
|
3497
|
+
* **Details**
|
|
3498
|
+
*
|
|
3499
|
+
* Services read by the content and completion handlers are request-level, so
|
|
3500
|
+
* providing them with `Layer.provide` doesn't satisfy them. Read
|
|
3501
|
+
* construction-time services in an enclosing `Layer.unwrap` and close over
|
|
3502
|
+
* them, and provide per-request services with MCP middleware.
|
|
3503
|
+
*
|
|
2481
3504
|
* @see {@link registerResource} for the Effect-level resource registration API
|
|
3505
|
+
* @see {@link middleware} for providing request-level dependencies
|
|
2482
3506
|
*
|
|
2483
3507
|
* @stability unstable
|
|
2484
3508
|
* @category layers
|
|
@@ -2498,11 +3522,19 @@ export const resource: {
|
|
|
2498
3522
|
R
|
|
2499
3523
|
>
|
|
2500
3524
|
}
|
|
2501
|
-
): Layer.Layer<never, never,
|
|
3525
|
+
): Layer.Layer<never, never, ResourceRequirements<R>>
|
|
2502
3526
|
/**
|
|
2503
3527
|
* Creates a layer that registers an MCP resource or resource template.
|
|
2504
3528
|
*
|
|
3529
|
+
* **Details**
|
|
3530
|
+
*
|
|
3531
|
+
* Services read by the content and completion handlers are request-level, so
|
|
3532
|
+
* providing them with `Layer.provide` doesn't satisfy them. Read
|
|
3533
|
+
* construction-time services in an enclosing `Layer.unwrap` and close over
|
|
3534
|
+
* them, and provide per-request services with MCP middleware.
|
|
3535
|
+
*
|
|
2505
3536
|
* @see {@link registerResource} for the Effect-level resource registration API
|
|
3537
|
+
* @see {@link middleware} for providing request-level dependencies
|
|
2506
3538
|
*
|
|
2507
3539
|
* @stability unstable
|
|
2508
3540
|
* @category layers
|
|
@@ -2524,28 +3556,13 @@ export const resource: {
|
|
|
2524
3556
|
E,
|
|
2525
3557
|
R
|
|
2526
3558
|
>
|
|
2527
|
-
}) => Layer.Layer<
|
|
2528
|
-
never,
|
|
2529
|
-
never,
|
|
2530
|
-
Exclude<
|
|
2531
|
-
| Schemas[number]["DecodingServices"]
|
|
2532
|
-
| Schemas[number]["EncodingServices"]
|
|
2533
|
-
| R
|
|
2534
|
-
| CompletionServices<Completions>,
|
|
2535
|
-
McpRequestContext
|
|
2536
|
-
>
|
|
2537
|
-
>
|
|
3559
|
+
}) => Layer.Layer<never, never, ResourceTemplateRequirements<Schemas, R, Completions>>
|
|
2538
3560
|
} = function() {
|
|
2539
3561
|
if (arguments.length === 1) {
|
|
2540
|
-
return Layer.effectDiscard(registerResource(arguments[0]))
|
|
2541
|
-
Layer.provide(McpServer.layer)
|
|
2542
|
-
)
|
|
3562
|
+
return Layer.effectDiscard(registerResource(arguments[0]))
|
|
2543
3563
|
}
|
|
2544
3564
|
const register = registerResource(...(arguments as any as [any, any]))
|
|
2545
|
-
return (options: any) =>
|
|
2546
|
-
Layer.effectDiscard(register(options)).pipe(
|
|
2547
|
-
Layer.provide(McpServer.layer)
|
|
2548
|
-
)
|
|
3565
|
+
return (options: any) => Layer.effectDiscard(register(options))
|
|
2549
3566
|
} as any
|
|
2550
3567
|
|
|
2551
3568
|
/**
|
|
@@ -2584,18 +3601,7 @@ export const registerPrompt = <
|
|
|
2584
3601
|
) => Effect.Effect<Array<PromptMessage> | string, E, R>
|
|
2585
3602
|
readonly annotations?: Context.Context<never> | undefined
|
|
2586
3603
|
}
|
|
2587
|
-
): Effect.Effect<
|
|
2588
|
-
void,
|
|
2589
|
-
never,
|
|
2590
|
-
| Exclude<
|
|
2591
|
-
| Schema.Struct.DecodingServices<Params>
|
|
2592
|
-
| Params[Extract<keyof Completions, keyof Params>]["EncodingServices"]
|
|
2593
|
-
| R
|
|
2594
|
-
| CompletionServices<Completions>,
|
|
2595
|
-
McpRequestContext
|
|
2596
|
-
>
|
|
2597
|
-
| McpServer
|
|
2598
|
-
> => {
|
|
3604
|
+
): Effect.Effect<void, never, PromptRequirements<Params, R, Completions>> => {
|
|
2599
3605
|
const args = Arr.empty<PromptArgument>()
|
|
2600
3606
|
const props: Record<string, Schema.Constraint> = options.parameters ?? {}
|
|
2601
3607
|
for (const [name, prop] of Object.entries(props)) {
|
|
@@ -2623,17 +3629,7 @@ export const registerPrompt = <
|
|
|
2623
3629
|
> = options.completion ?? {}
|
|
2624
3630
|
return Effect.gen(function*() {
|
|
2625
3631
|
const registry = yield* McpServer
|
|
2626
|
-
const services =
|
|
2627
|
-
yield* Effect.context<
|
|
2628
|
-
Exclude<
|
|
2629
|
-
| R
|
|
2630
|
-
| Schema.Struct.DecodingServices<Params>
|
|
2631
|
-
| Params[Extract<keyof Completions, keyof Params>]["EncodingServices"]
|
|
2632
|
-
| CompletionServices<Completions>,
|
|
2633
|
-
McpRequestContext
|
|
2634
|
-
>
|
|
2635
|
-
>()
|
|
2636
|
-
)
|
|
3632
|
+
const services = yield* Effect.context<never>()
|
|
2637
3633
|
const completions: Record<
|
|
2638
3634
|
string,
|
|
2639
3635
|
(
|
|
@@ -2642,41 +3638,19 @@ export const registerPrompt = <
|
|
|
2642
3638
|
) => Effect.Effect<CompleteResult, InternalError, McpRequestContext>
|
|
2643
3639
|
> = Object.create(null)
|
|
2644
3640
|
for (const [param, handle] of Object.entries(completion)) {
|
|
2645
|
-
|
|
2646
|
-
const handler = (
|
|
2647
|
-
input: string,
|
|
2648
|
-
context: CompletionContext
|
|
2649
|
-
) =>
|
|
2650
|
-
handle(input, context).pipe(
|
|
2651
|
-
Effect.flatMap(encodeArray),
|
|
2652
|
-
Effect.map((values) => ({
|
|
2653
|
-
completion: {
|
|
2654
|
-
values: values as Array<string>,
|
|
2655
|
-
total: values.length,
|
|
2656
|
-
hasMore: false
|
|
2657
|
-
}
|
|
2658
|
-
})),
|
|
2659
|
-
Effect.catchCause((cause) => {
|
|
2660
|
-
const prettyError = Cause.prettyErrors(cause)[0]
|
|
2661
|
-
return Effect.fail(new InternalError({ message: prettyError.message }))
|
|
2662
|
-
}),
|
|
2663
|
-
Effect.provide(services)
|
|
2664
|
-
)
|
|
2665
|
-
completions[param] = handler as any
|
|
3641
|
+
completions[param] = completionHandler(handle, Schema.encodeUnknownEffect(Schema.Array(props[param])))
|
|
2666
3642
|
}
|
|
2667
3643
|
yield* registry.addPrompt({
|
|
2668
3644
|
prompt,
|
|
2669
3645
|
completions,
|
|
3646
|
+
services,
|
|
2670
3647
|
annotations: options.annotations ?? Context.empty(),
|
|
2671
3648
|
handle: (params) =>
|
|
2672
3649
|
decode(params).pipe(
|
|
2673
3650
|
Effect.mapError((error) => new InvalidParams({ message: error.message })),
|
|
2674
3651
|
Effect.flatMap((params) =>
|
|
2675
3652
|
options.content(params as any).pipe(
|
|
2676
|
-
Effect.catchCause(
|
|
2677
|
-
const prettyError = Cause.prettyErrors(cause)[0]
|
|
2678
|
-
return Effect.fail(new InternalError({ message: prettyError.message }))
|
|
2679
|
-
})
|
|
3653
|
+
Effect.catchCause(handlerFailureToInternalError)
|
|
2680
3654
|
)
|
|
2681
3655
|
),
|
|
2682
3656
|
Effect.map((messages) => {
|
|
@@ -2687,9 +3661,8 @@ export const registerPrompt = <
|
|
|
2687
3661
|
}] :
|
|
2688
3662
|
messages
|
|
2689
3663
|
return new GetPromptResult({ messages, description: prompt.description })
|
|
2690
|
-
})
|
|
2691
|
-
|
|
2692
|
-
)
|
|
3664
|
+
})
|
|
3665
|
+
) as Effect.Effect<GetPromptResult, InvalidParams | InternalError>
|
|
2693
3666
|
})
|
|
2694
3667
|
})
|
|
2695
3668
|
}
|
|
@@ -2697,7 +3670,15 @@ export const registerPrompt = <
|
|
|
2697
3670
|
/**
|
|
2698
3671
|
* Creates a layer that registers an MCP prompt.
|
|
2699
3672
|
*
|
|
3673
|
+
* **Details**
|
|
3674
|
+
*
|
|
3675
|
+
* Services read by the content and completion handlers are request-level, so
|
|
3676
|
+
* providing them with `Layer.provide` doesn't satisfy them. Read
|
|
3677
|
+
* construction-time services in an enclosing `Layer.unwrap` and close over
|
|
3678
|
+
* them, and provide per-request services with MCP middleware.
|
|
3679
|
+
*
|
|
2700
3680
|
* @see {@link registerPrompt} for the Effect-level prompt registration API
|
|
3681
|
+
* @see {@link middleware} for providing request-level dependencies
|
|
2701
3682
|
*
|
|
2702
3683
|
* @stability unstable
|
|
2703
3684
|
* @category layers
|
|
@@ -2725,20 +3706,7 @@ export const prompt = <
|
|
|
2725
3706
|
) => Effect.Effect<Array<PromptMessage> | string, E, R>
|
|
2726
3707
|
readonly annotations?: Context.Context<never> | undefined
|
|
2727
3708
|
}
|
|
2728
|
-
): Layer.Layer<
|
|
2729
|
-
never,
|
|
2730
|
-
never,
|
|
2731
|
-
Exclude<
|
|
2732
|
-
| Schema.Struct.DecodingServices<Params>
|
|
2733
|
-
| Params[Extract<keyof Completions, keyof Params>]["EncodingServices"]
|
|
2734
|
-
| R
|
|
2735
|
-
| CompletionServices<Completions>,
|
|
2736
|
-
McpRequestContext
|
|
2737
|
-
>
|
|
2738
|
-
> =>
|
|
2739
|
-
Layer.effectDiscard(registerPrompt(options)).pipe(
|
|
2740
|
-
Layer.provide(McpServer.layer)
|
|
2741
|
-
)
|
|
3709
|
+
): Layer.Layer<never, never, PromptRequirements<Params, R, Completions>> => Layer.effectDiscard(registerPrompt(options))
|
|
2742
3710
|
|
|
2743
3711
|
/**
|
|
2744
3712
|
* Collects structured input from the current MCP client and decodes the
|
|
@@ -2798,6 +3766,22 @@ export const clientCapabilities: Effect.Effect<
|
|
|
2798
3766
|
McpRequestContext
|
|
2799
3767
|
> = McpRequestContext.useSync((_) => _.clientCapabilities)
|
|
2800
3768
|
|
|
3769
|
+
/**
|
|
3770
|
+
* Decodes an `Mcp-Name` header, including base64-wrapped values.
|
|
3771
|
+
* Returns `undefined` for malformed values.
|
|
3772
|
+
*
|
|
3773
|
+
* **Details**
|
|
3774
|
+
*
|
|
3775
|
+
* Use in `HttpRouter.middleware` to identify the tool, prompt or resource
|
|
3776
|
+
* targeted by a `2026-07-28` request. Earlier protocols carry the name only
|
|
3777
|
+
* in the JSON-RPC body.
|
|
3778
|
+
*
|
|
3779
|
+
* @stability unstable
|
|
3780
|
+
* @category decoding
|
|
3781
|
+
* @since 4.0.0
|
|
3782
|
+
*/
|
|
3783
|
+
export const decodeNameHeader = (value: string): string | undefined => McpProtocolInternal.decodeRoutingHeader(value)
|
|
3784
|
+
|
|
2801
3785
|
// -----------------------------------------------------------------------------
|
|
2802
3786
|
// Internal
|
|
2803
3787
|
// -----------------------------------------------------------------------------
|