effect 4.0.7 → 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/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 +9 -3
- 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/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 +164 -7
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +11 -1
- package/dist/Effect.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/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/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/Pool.d.ts +51 -0
- package/dist/Pool.d.ts.map +1 -1
- package/dist/Pool.js +59 -9
- package/dist/Pool.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/Schedule.d.ts +18 -1
- package/dist/Schedule.d.ts.map +1 -1
- package/dist/Schedule.js +7 -2
- package/dist/Schedule.js.map +1 -1
- package/dist/Schema.d.ts +666 -41
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +650 -0
- package/dist/Schema.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/SchemaRepresentation.d.ts +14 -0
- package/dist/SchemaRepresentation.d.ts.map +1 -1
- package/dist/SchemaRepresentation.js +16 -0
- package/dist/SchemaRepresentation.js.map +1 -1
- package/dist/SchemaTransformation.d.ts +8 -3
- package/dist/SchemaTransformation.d.ts.map +1 -1
- package/dist/SchemaTransformation.js +6 -3
- 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 +40 -0
- package/dist/Semaphore.js.map +1 -1
- package/dist/Stream.d.ts +13 -4
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +9 -0
- package/dist/Stream.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/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/McpServer.d.ts +630 -29
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +562 -116
- 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/Response.d.ts +1 -25
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js +1 -10
- package/dist/ai/Response.js.map +1 -1
- package/dist/ai/Tool.d.ts +19 -1
- package/dist/ai/Tool.d.ts.map +1 -1
- package/dist/ai/Tool.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 +6 -0
- package/dist/cli/Argument.d.ts.map +1 -1
- package/dist/cli/Argument.js +2 -0
- package/dist/cli/Argument.js.map +1 -1
- package/dist/cli/CliOutput.d.ts +65 -1
- package/dist/cli/CliOutput.d.ts.map +1 -1
- package/dist/cli/CliOutput.js +94 -37
- package/dist/cli/CliOutput.js.map +1 -1
- package/dist/cli/Command.d.ts +23 -0
- package/dist/cli/Command.d.ts.map +1 -1
- package/dist/cli/Command.js +8 -0
- package/dist/cli/Command.js.map +1 -1
- package/dist/cli/Flag.d.ts +107 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +37 -0
- package/dist/cli/Flag.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 +6 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +2 -0
- 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/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/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +90 -28
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/ShardingConfig.d.ts +72 -6
- 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/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 +23 -8
- package/dist/cluster/SqlRunnerStorage.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/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/Toml.d.ts +17 -3
- package/dist/encoding/Toml.d.ts.map +1 -1
- package/dist/encoding/Toml.js +104 -16
- 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.js +2 -2
- 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/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 +143 -1
- 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 +79 -8
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +65 -5
- package/dist/http/HttpClient.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 +2 -3
- 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/HttpServerRequest.d.ts +5 -2
- package/dist/http/HttpServerRequest.d.ts.map +1 -1
- package/dist/http/HttpServerRequest.js +6 -17
- 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/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/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/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/decompression.js +3 -2
- package/dist/http/internal/decompression.js.map +1 -1
- package/dist/http/internal/urlParams.js +8 -0
- package/dist/http/internal/urlParams.js.map +1 -1
- package/dist/http-api/HttpApiBuilder.js +19 -5
- package/dist/http-api/HttpApiBuilder.js.map +1 -1
- package/dist/http-api/HttpApiClient.d.ts +63 -0
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +51 -0
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/http-api/HttpApiEndpoint.js +14 -5
- 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 +76 -14
- package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
- package/dist/http-api/HttpApiSchema.js +53 -0
- package/dist/http-api/HttpApiSchema.js.map +1 -1
- 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/effect.js +25 -14
- package/dist/internal/effect.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/matcher.js +10 -0
- 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/toCodeDocument.js +6 -3
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- 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/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/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/process/ChildProcess.d.ts +207 -67
- 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 +5 -0
- package/dist/process/ChildProcessSpawner.d.ts.map +1 -1
- 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/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 +50 -16
- 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.map +1 -1
- package/dist/rpc/RpcSerialization.js +6 -0
- 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 -66
- package/dist/rpc/RpcServer.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 +0 -19
- package/dist/sql/Migrator.d.ts.map +1 -1
- package/dist/sql/Migrator.js +3 -48
- 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.map +1 -1
- package/dist/sql/SqlClient.js +5 -9
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/sql/Statement.d.ts +20 -6
- package/dist/sql/Statement.d.ts.map +1 -1
- package/dist/sql/Statement.js +0 -13
- 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/internal/crypto.js +9 -8
- package/dist/workflow/internal/crypto.js.map +1 -1
- package/package.json +3 -1
- package/src/BigDecimal.ts +3 -0
- package/src/Channel.ts +17 -11
- package/src/Config.ts +7 -1
- package/src/Context.ts +34 -10
- package/src/Cron.ts +178 -29
- package/src/Duration.ts +140 -0
- package/src/Effect.ts +914 -85
- package/src/FileSystem.ts +65 -4
- package/src/Glob.ts +205 -0
- package/src/Match.ts +127 -0
- package/src/Pool.ts +73 -15
- package/src/Random.ts +3 -3
- package/src/RcMap.ts +5 -1
- package/src/Schedule.ts +26 -3
- package/src/Schema.ts +1189 -62
- package/src/SchemaGetter.ts +27 -11
- package/src/SchemaRepresentation.ts +19 -0
- package/src/SchemaTransformation.ts +8 -3
- package/src/ScopedCache.ts +5 -9
- package/src/Semaphore.ts +141 -0
- package/src/Stream.ts +15 -6
- package/src/Terminal.ts +19 -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/McpServer.ts +1269 -286
- package/src/ai/McpTest.ts +380 -0
- package/src/ai/Response.ts +2 -22
- package/src/ai/Tool.ts +27 -8
- 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 +6 -0
- package/src/cli/CliOutput.ts +117 -49
- package/src/cli/Command.ts +23 -0
- package/src/cli/Flag.ts +107 -0
- package/src/cli/HelpDoc.ts +18 -1
- package/src/cli/Param.ts +6 -0
- package/src/cli/Primitive.ts +16 -1
- package/src/cli/Prompt.ts +1 -0
- package/src/cli/internal/help.ts +21 -9
- package/src/cluster/Sharding.ts +93 -26
- package/src/cluster/ShardingConfig.ts +41 -3
- package/src/cluster/SingleRunner.ts +3 -3
- package/src/cluster/SqlMessageStorage.ts +49 -17
- package/src/cluster/SqlRunnerStorage.ts +37 -27
- 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/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/Toml.ts +85 -20
- 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 +2 -2
- 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/identityRootSecretDerivation.ts +93 -123
- package/src/eventlog/internal/remoteCompaction.ts +92 -0
- package/src/http/Cookies.ts +281 -1
- package/src/http/FetchHttpClient.ts +88 -16
- package/src/http/HttpClient.ts +89 -22
- package/src/http/HttpClientRequest.ts +12 -9
- package/src/http/HttpClientResponse.ts +3 -2
- package/src/http/HttpMethod.ts +10 -2
- package/src/http/HttpServerRequest.ts +15 -30
- package/src/http/HttpServerResponse.ts +3 -2
- package/src/http/HttpTraceContext.ts +7 -4
- package/src/http/ProblemDetails.ts +149 -0
- package/src/http/index.ts +6 -0
- package/src/http/internal/decompression.ts +4 -4
- package/src/http/internal/urlParams.ts +8 -0
- package/src/http-api/HttpApiBuilder.ts +24 -12
- package/src/http-api/HttpApiClient.ts +67 -1
- package/src/http-api/HttpApiEndpoint.ts +14 -5
- package/src/http-api/HttpApiError.ts +250 -0
- package/src/http-api/HttpApiMiddleware.ts +95 -1
- package/src/http-api/HttpApiSchema.ts +105 -14
- package/src/index.ts +6 -6
- package/src/internal/effect.ts +34 -18
- package/src/internal/glob.ts +736 -0
- package/src/internal/matcher.ts +17 -0
- package/src/internal/persistence.ts +11 -0
- package/src/internal/rcRef.ts +4 -1
- package/src/internal/schema/toCodeDocument.ts +7 -3
- 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/OtlpResource.ts +9 -1
- package/src/persistence/KeyValueStore.ts +219 -22
- package/src/persistence/PersistedQueue.ts +128 -59
- package/src/persistence/Persistence.ts +20 -13
- package/src/process/ChildProcess.ts +255 -260
- package/src/process/ChildProcessSpawner.ts +5 -0
- package/src/process/CommandLine.ts +630 -0
- package/src/process/index.ts +6 -0
- package/src/reactivity/Atom.ts +5 -5
- package/src/reactivity/AtomRegistry.ts +1 -1
- package/src/rpc/RpcClient.ts +62 -26
- package/src/rpc/RpcMessage.ts +10 -1
- package/src/rpc/RpcSerialization.ts +3 -0
- package/src/rpc/RpcServer.ts +176 -78
- package/src/schema/Model.ts +26 -3
- package/src/sql/Migrator.ts +4 -63
- package/src/sql/MigratorFileSystem.ts +71 -0
- package/src/sql/SqlClient.ts +2 -16
- package/src/sql/Statement.ts +8 -7
- package/src/sql/index.ts +1 -1
- package/src/testing/index.ts +0 -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/dist/ai/McpServer.js
CHANGED
|
@@ -16,6 +16,7 @@ import * as Cause from "../Cause.js";
|
|
|
16
16
|
import * as Context from "../Context.js";
|
|
17
17
|
import * as Data from "../Data.js";
|
|
18
18
|
import * as Deferred from "../Deferred.js";
|
|
19
|
+
import * as Duration from "../Duration.js";
|
|
19
20
|
import * as Effect from "../Effect.js";
|
|
20
21
|
import * as ErrorReporter from "../ErrorReporter.js";
|
|
21
22
|
import * as Exit from "../Exit.js";
|
|
@@ -43,6 +44,7 @@ import * as Schema from "../Schema.js";
|
|
|
43
44
|
import * as SchemaAST from "../SchemaAST.js";
|
|
44
45
|
import * as Scope from "../Scope.js";
|
|
45
46
|
import * as Stream from "../Stream.js";
|
|
47
|
+
import * as Tracer from "../Tracer.js";
|
|
46
48
|
import * as AiError from "./AiError.js";
|
|
47
49
|
import * as McpCore from "./internal/mcpCore.js";
|
|
48
50
|
import * as McpProtocolInternal from "./internal/mcpProtocol.js";
|
|
@@ -106,8 +108,18 @@ const toInternalServerNotification = message => {
|
|
|
106
108
|
return undefined;
|
|
107
109
|
}
|
|
108
110
|
};
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
const middlewareKeyPrefix = "effect/ai/McpServer/Middleware-";
|
|
112
|
+
// Do not capture request services or middleware stacks at registration.
|
|
113
|
+
const requestServiceKeys = /*#__PURE__*/new Set([McpRequestContext.key, McpServerClient.key, HttpServerRequest.HttpServerRequest.key, HttpServerRequest.ParsedSearchParams.key, HttpRouter.RouteContext.key, CurrentLogLevel.key, Scope.Scope.key, Tracer.ParentSpan.key]);
|
|
114
|
+
const omitRequestServices = context => {
|
|
115
|
+
const services = new Map();
|
|
116
|
+
for (const [key, value] of context.mapUnsafe) {
|
|
117
|
+
if (!requestServiceKeys.has(key) && !key.startsWith(middlewareKeyPrefix)) {
|
|
118
|
+
services.set(key, value);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return Context.makeUnsafe(services);
|
|
122
|
+
};
|
|
111
123
|
const provideInvocationContext = (effect, invocation) => {
|
|
112
124
|
let provided = Effect.provideService(effect, McpRequestContext, invocation.requestContext);
|
|
113
125
|
const requestMetadata = invocation.requestContext.requestMetadata;
|
|
@@ -117,6 +129,329 @@ const provideInvocationContext = (effect, invocation) => {
|
|
|
117
129
|
}
|
|
118
130
|
return invocation.serverClient === undefined ? provided : Effect.provideService(provided, McpServerClient, invocation.serverClient);
|
|
119
131
|
};
|
|
132
|
+
const MiddlewareTypeId = "~effect/ai/McpServer/Middleware";
|
|
133
|
+
/**
|
|
134
|
+
* Creates MCP middleware that runs around `tools/call`, `resources/read`,
|
|
135
|
+
* `prompts/get` and `completion/complete` requests.
|
|
136
|
+
*
|
|
137
|
+
* **Details**
|
|
138
|
+
*
|
|
139
|
+
* Middleware is how request-level dependencies are satisfied: declare the
|
|
140
|
+
* services it provides with `middleware<{ provides: S }>()` and provide them to
|
|
141
|
+
* the handler effect. It receives the request headers, session id and request
|
|
142
|
+
* context, so it can resolve the current user per request.
|
|
143
|
+
*
|
|
144
|
+
* Pass a function, or an Effect that builds the function. Services the Effect
|
|
145
|
+
* reads are requirements of the middleware layer. Services the function reads
|
|
146
|
+
* per request, other than `McpRequestContext`, are per-request requirements
|
|
147
|
+
* of the result; see {@link Middleware} for how they are met.
|
|
148
|
+
*
|
|
149
|
+
* Failures must be `McpErrorBase` values. A middleware failure is sent as a
|
|
150
|
+
* JSON-RPC error with its `code`, `message` and `data`, never as a tool
|
|
151
|
+
* result. Pick custom codes from the implementation-defined range
|
|
152
|
+
* (-32000 to -32019): any numeric `code` is sent as is. Defects are logged,
|
|
153
|
+
* reported to the `ErrorReporter` and sent as `InternalError("Internal error")`.
|
|
154
|
+
* Interruption propagates.
|
|
155
|
+
*
|
|
156
|
+
* Local middleware runs inside global middleware, and middleware provided both
|
|
157
|
+
* locally and globally runs once. Middleware never runs for `initialize`. It
|
|
158
|
+
* runs for list requests only when it wraps a {@link visibility}, so that the
|
|
159
|
+
* visibility check can read the services it provides.
|
|
160
|
+
*
|
|
161
|
+
* **Example** (Resolving the current user per request)
|
|
162
|
+
*
|
|
163
|
+
* ```ts
|
|
164
|
+
* import { Context, Effect, Layer, Schema } from "effect"
|
|
165
|
+
* import { McpSchema, McpServer, Tool, Toolkit } from "effect/ai"
|
|
166
|
+
*
|
|
167
|
+
* class CurrentUser extends Context.Service<CurrentUser, { readonly id: string }>()("CurrentUser") {}
|
|
168
|
+
*
|
|
169
|
+
* class Unauthorized extends Schema.Error<Unauthorized>("Unauthorized")({
|
|
170
|
+
* ...McpSchema.McpErrorBase.fields,
|
|
171
|
+
* _tag: Schema.tag("Unauthorized"),
|
|
172
|
+
* code: Schema.tag(-32001)
|
|
173
|
+
* }) {}
|
|
174
|
+
*
|
|
175
|
+
* const WhoAmI = Tool.make("WhoAmI", { success: Schema.String, dependencies: [CurrentUser] })
|
|
176
|
+
* const Tools = Toolkit.make(WhoAmI)
|
|
177
|
+
*
|
|
178
|
+
* const Auth = McpServer.middleware<{ provides: CurrentUser }>()((effect, { headers }) => {
|
|
179
|
+
* const token = headers["authorization"]
|
|
180
|
+
* return token === undefined
|
|
181
|
+
* ? Effect.fail(new Unauthorized({ message: "Missing credentials" }))
|
|
182
|
+
* : Effect.provideService(effect, CurrentUser, { id: token })
|
|
183
|
+
* })
|
|
184
|
+
*
|
|
185
|
+
* const Registrations = McpServer.toolkit(Tools).pipe(
|
|
186
|
+
* Layer.provide(Auth.layer),
|
|
187
|
+
* Layer.provide(Tools.toLayer({
|
|
188
|
+
* WhoAmI: () => Effect.map(CurrentUser, (user) => user.id)
|
|
189
|
+
* }))
|
|
190
|
+
* )
|
|
191
|
+
* ```
|
|
192
|
+
*
|
|
193
|
+
* @stability unstable
|
|
194
|
+
* @category middleware
|
|
195
|
+
* @since 4.0.0
|
|
196
|
+
*/
|
|
197
|
+
export const middleware = function () {
|
|
198
|
+
if (arguments.length === 0) {
|
|
199
|
+
return makeMiddleware;
|
|
200
|
+
}
|
|
201
|
+
return makeMiddleware(arguments[0], arguments[1]);
|
|
202
|
+
};
|
|
203
|
+
/**
|
|
204
|
+
* Creates middleware that hides registrations per request.
|
|
205
|
+
*
|
|
206
|
+
* **Details**
|
|
207
|
+
*
|
|
208
|
+
* The check runs for every registration the middleware is provided to, on list
|
|
209
|
+
* requests and on calls, reads, gets and completions. When it returns `false`
|
|
210
|
+
* the registration is left out of list results, and requests for it fail as if
|
|
211
|
+
* it was not registered.
|
|
212
|
+
*
|
|
213
|
+
* The result is a `Middleware` and composes like one. The check receives the
|
|
214
|
+
* same {@link MiddlewareOptions} as middleware, and services it reads per
|
|
215
|
+
* request, other than `McpRequestContext`, are met the same way. Scope a
|
|
216
|
+
* visibility to some tools by providing its layer to their toolkit only, or
|
|
217
|
+
* branch on `target`.
|
|
218
|
+
*
|
|
219
|
+
* On a list request, the check and the middleware outside the innermost
|
|
220
|
+
* visibility run once for each registration. Middleware inside it does not
|
|
221
|
+
* run. A failure of that middleware or of a check fails the whole list
|
|
222
|
+
* request. It never hides a registration.
|
|
223
|
+
*
|
|
224
|
+
* Unlike `EnabledWhen`, a visibility runs the middleware around it on list
|
|
225
|
+
* requests, and middleware sees requests for hidden registrations.
|
|
226
|
+
*
|
|
227
|
+
* **Example** (Hiding admin tools from other users)
|
|
228
|
+
*
|
|
229
|
+
* ```ts
|
|
230
|
+
* import { Context, Effect, Layer, Schema } from "effect"
|
|
231
|
+
* import { McpServer, Tool, Toolkit } from "effect/ai"
|
|
232
|
+
*
|
|
233
|
+
* class CurrentUser extends Context.Service<CurrentUser, { readonly isAdmin: boolean }>()("CurrentUser") {}
|
|
234
|
+
*
|
|
235
|
+
* const AdminTools = Toolkit.make(Tool.make("DeleteUser", { success: Schema.String }))
|
|
236
|
+
*
|
|
237
|
+
* const Auth = McpServer.middleware<{ provides: CurrentUser }>()((effect, { headers }) =>
|
|
238
|
+
* Effect.provideService(effect, CurrentUser, { isAdmin: headers["x-role"] === "admin" })
|
|
239
|
+
* )
|
|
240
|
+
* const AdminOnly = McpServer.visibility(() => Effect.map(CurrentUser, (user) => user.isAdmin))
|
|
241
|
+
*
|
|
242
|
+
* const Registrations = McpServer.toolkit(AdminTools).pipe(
|
|
243
|
+
* Layer.provide(AdminOnly.combine(Auth).layer),
|
|
244
|
+
* Layer.provide(AdminTools.toLayer({ DeleteUser: () => Effect.succeed("deleted") }))
|
|
245
|
+
* )
|
|
246
|
+
* ```
|
|
247
|
+
*
|
|
248
|
+
* @see {@link middleware} for providing the services a check reads
|
|
249
|
+
*
|
|
250
|
+
* @stability unstable
|
|
251
|
+
* @category middleware
|
|
252
|
+
* @since 4.0.0
|
|
253
|
+
*/
|
|
254
|
+
export const visibility = (check, options) => makeMiddleware(Effect.isEffect(check) ? Effect.map(check, makeGate) : makeGate(check), options);
|
|
255
|
+
// Raised by a visibility gate. It is left out of the types because `makeInvoke`
|
|
256
|
+
// replaces it with the not-found error of the request. It still has the shape
|
|
257
|
+
// of an MCP error, since middleware outside the gate sees it as one.
|
|
258
|
+
class Hidden extends /*#__PURE__*/Data.TaggedError("effect/ai/McpServer/Hidden") {}
|
|
259
|
+
const failHidden = /*#__PURE__*/Effect.fail(/*#__PURE__*/new Hidden({
|
|
260
|
+
code: McpSchema.INVALID_PARAMS_ERROR_CODE,
|
|
261
|
+
message: "Not found"
|
|
262
|
+
}));
|
|
263
|
+
// Marks the middleware functions created by `visibility`.
|
|
264
|
+
const gates = /*#__PURE__*/new WeakSet();
|
|
265
|
+
const makeGate = check => {
|
|
266
|
+
const gate = (effect, options) => Effect.flatMap(check(options), visible => visible ? effect : failHidden);
|
|
267
|
+
gates.add(gate);
|
|
268
|
+
return gate;
|
|
269
|
+
};
|
|
270
|
+
class MiddlewareFn extends /*#__PURE__*/Context.Service()("effect/ai/McpServer/MiddlewareFn") {}
|
|
271
|
+
const makeMiddleware = (fn, options) => {
|
|
272
|
+
const middleware = new MiddlewareImpl(Effect.isEffect(fn) ? Layer.effect(MiddlewareFn)(fn) : Layer.succeed(MiddlewareFn, fn));
|
|
273
|
+
return options?.global ? middleware.layerGlobal : middleware;
|
|
274
|
+
};
|
|
275
|
+
let middlewareId = 0;
|
|
276
|
+
class MiddlewareImpl {
|
|
277
|
+
[MiddlewareTypeId] = {};
|
|
278
|
+
layer;
|
|
279
|
+
layerGlobal;
|
|
280
|
+
layerFn;
|
|
281
|
+
dependencies;
|
|
282
|
+
constructor(layerFn, dependencies) {
|
|
283
|
+
this.layerFn = layerFn;
|
|
284
|
+
this.dependencies = dependencies;
|
|
285
|
+
const contextKey = `${middlewareKeyPrefix}${++middlewareId}`;
|
|
286
|
+
this.layer = Layer.effectContext(Effect.gen(function* () {
|
|
287
|
+
const stack = [yield* MiddlewareFn];
|
|
288
|
+
if (dependencies) {
|
|
289
|
+
const memoMap = yield* Layer.CurrentMemoMap;
|
|
290
|
+
const scope = yield* Effect.scope;
|
|
291
|
+
stack.push(...getMiddleware(yield* Layer.buildWithMemoMap(dependencies, memoMap, scope)));
|
|
292
|
+
}
|
|
293
|
+
return Context.makeUnsafe(new Map([[contextKey, stack]]));
|
|
294
|
+
})).pipe(Layer.provide(layerFn));
|
|
295
|
+
this.layerGlobal = Layer.effectDiscard(Effect.gen(function* () {
|
|
296
|
+
const stack = Context.getOrUndefinedUnsafe(yield* Effect.context(), contextKey);
|
|
297
|
+
const {
|
|
298
|
+
globalMiddleware
|
|
299
|
+
} = internalState.get(yield* McpServer);
|
|
300
|
+
yield* Effect.acquireRelease(Effect.sync(() => {
|
|
301
|
+
globalMiddleware.push(...stack);
|
|
302
|
+
}), () => Effect.sync(() => {
|
|
303
|
+
for (const fn of stack) {
|
|
304
|
+
const index = globalMiddleware.indexOf(fn);
|
|
305
|
+
if (index !== -1) globalMiddleware.splice(index, 1);
|
|
306
|
+
}
|
|
307
|
+
}));
|
|
308
|
+
})).pipe(Layer.provide(this.layer));
|
|
309
|
+
}
|
|
310
|
+
combine(other) {
|
|
311
|
+
return new MiddlewareImpl(this.layerFn, this.dependencies ? Layer.provideMerge(this.dependencies, other.layer) : other.layer);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
// The innermost middleware comes first.
|
|
315
|
+
const getMiddleware = context => {
|
|
316
|
+
const stacks = [];
|
|
317
|
+
let maxLength = 0;
|
|
318
|
+
for (const [key, value] of context.mapUnsafe) {
|
|
319
|
+
if (key.startsWith(middlewareKeyPrefix)) {
|
|
320
|
+
stacks.push(value);
|
|
321
|
+
maxLength = Math.max(maxLength, value.length);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
const unique = new Set();
|
|
325
|
+
for (let i = maxLength - 1; i >= 0; i--) {
|
|
326
|
+
for (const stack of stacks) {
|
|
327
|
+
if (i < stack.length) unique.add(stack[i]);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return Arr.fromIterable(unique).reverse();
|
|
331
|
+
};
|
|
332
|
+
const isMcpError = error => Predicate.hasProperty(error, "code") && typeof error.code === "number" && Predicate.hasProperty(error, "message") && typeof error.message === "string";
|
|
333
|
+
// Distinguishes handler failures from failures raised or rewritten by middleware.
|
|
334
|
+
const HandlerFailure = /*#__PURE__*/Context.Reference("effect/ai/McpServer/HandlerFailure", {
|
|
335
|
+
defaultValue: () => false
|
|
336
|
+
});
|
|
337
|
+
const handlerFailure = /*#__PURE__*/Context.make(HandlerFailure, true);
|
|
338
|
+
const internalError = /*#__PURE__*/new InternalError({
|
|
339
|
+
message: "Internal error"
|
|
340
|
+
});
|
|
341
|
+
const rejectWith = error => Effect.fail(new McpCore.RequestRejected({
|
|
342
|
+
code: error.code,
|
|
343
|
+
message: error.message,
|
|
344
|
+
data: error.data,
|
|
345
|
+
error
|
|
346
|
+
}));
|
|
347
|
+
const notFound = (method, target) => {
|
|
348
|
+
switch (method) {
|
|
349
|
+
case "tools/call":
|
|
350
|
+
return new McpCore.ToolNotFound({
|
|
351
|
+
name: target
|
|
352
|
+
});
|
|
353
|
+
case "resources/read":
|
|
354
|
+
return new McpCore.ResourceNotFound({
|
|
355
|
+
uri: target
|
|
356
|
+
});
|
|
357
|
+
case "prompts/get":
|
|
358
|
+
return new McpCore.PromptNotFound({
|
|
359
|
+
name: target
|
|
360
|
+
});
|
|
361
|
+
case "completion/complete":
|
|
362
|
+
return new InvalidParams({
|
|
363
|
+
message: "Unknown completion reference or argument"
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
const isHidden = error => error instanceof Hidden;
|
|
368
|
+
// Recovers a request rejected by a visibility gate. Any other cause, including
|
|
369
|
+
// one that also holds an interrupt, is propagated unchanged.
|
|
370
|
+
const catchHidden = onHidden => self => Effect.catchCause(self, cause => {
|
|
371
|
+
const failure = Cause.findFail(cause);
|
|
372
|
+
return !Cause.hasInterrupts(cause) && Result.isSuccess(failure) && isHidden(failure.success.error) ? onHidden() : Effect.failCause(cause);
|
|
373
|
+
});
|
|
374
|
+
// The innermost middleware comes first. Middleware provided both locally and
|
|
375
|
+
// globally runs once, at its outermost position.
|
|
376
|
+
const middlewareStack = (localMiddleware, globalMiddleware) => {
|
|
377
|
+
if (globalMiddleware.length === 0) {
|
|
378
|
+
return localMiddleware;
|
|
379
|
+
}
|
|
380
|
+
if (localMiddleware.length === 0) {
|
|
381
|
+
return globalMiddleware;
|
|
382
|
+
}
|
|
383
|
+
const stack = [...localMiddleware, ...globalMiddleware];
|
|
384
|
+
return stack.filter((fn, index) => stack.lastIndexOf(fn) === index);
|
|
385
|
+
};
|
|
386
|
+
// Runs a handler inside middleware. The handler's own failures pass through, a
|
|
387
|
+
// visibility gate fails with `Hidden`, and other failures become
|
|
388
|
+
// `RequestRejected`: middleware failures as JSON-RPC errors, anything else as
|
|
389
|
+
// a reported internal error.
|
|
390
|
+
const runMiddleware = (handler, middleware, invocation, request) => {
|
|
391
|
+
const effect = middleware.length === 0 ? handler : Effect.withFiber(fiber => {
|
|
392
|
+
const headers = Context.getOrUndefined(fiber.context, HttpServerRequest.HttpServerRequest)?.headers ?? Headers.empty;
|
|
393
|
+
const options = {
|
|
394
|
+
...request,
|
|
395
|
+
requestContext: invocation.requestContext,
|
|
396
|
+
headers,
|
|
397
|
+
sessionId: headers[MCP_SESSION_ID_HEADER]
|
|
398
|
+
};
|
|
399
|
+
const handled = Effect.catchCause(handler, cause => Effect.failCause(Cause.annotate(cause, handlerFailure)));
|
|
400
|
+
return middleware.reduce((effect, fn) => fn(effect, options), handled);
|
|
401
|
+
});
|
|
402
|
+
return provideInvocationContext(effect, invocation).pipe(Effect.catchCause(cause => {
|
|
403
|
+
if (Cause.hasInterrupts(cause)) {
|
|
404
|
+
return Effect.failCause(cause);
|
|
405
|
+
}
|
|
406
|
+
const failure = Cause.findFail(cause);
|
|
407
|
+
if (Result.isSuccess(failure) && !Cause.hasDies(cause)) {
|
|
408
|
+
const error = failure.success.error;
|
|
409
|
+
if (isHidden(error)) {
|
|
410
|
+
return Effect.fail(error);
|
|
411
|
+
}
|
|
412
|
+
if (middleware.length === 0 || Context.get(Cause.reasonAnnotations(failure.success), HandlerFailure)) {
|
|
413
|
+
return Effect.failCause(cause);
|
|
414
|
+
}
|
|
415
|
+
if (isMcpError(error)) {
|
|
416
|
+
return rejectWith(error);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return Effect.logError(cause).pipe(Effect.andThen(ErrorReporter.report(cause)), Effect.andThen(rejectWith(internalError)));
|
|
420
|
+
}));
|
|
421
|
+
};
|
|
422
|
+
// Request services override captured services; global middleware wraps local middleware.
|
|
423
|
+
const makeInvoke = (context, globalMiddleware) => {
|
|
424
|
+
const services = context === undefined ? Context.empty() : omitRequestServices(context);
|
|
425
|
+
const localMiddleware = context === undefined ? [] : getMiddleware(context);
|
|
426
|
+
const invoke = (handler, invocation, request) => runMiddleware(services.mapUnsafe.size === 0 ? handler : Effect.updateContext(handler, context => Context.merge(services, context)), middlewareStack(localMiddleware, globalMiddleware), invocation, request).pipe(catchHidden(() => Effect.fail(notFound(request.method, request.target))));
|
|
427
|
+
// On list requests only the middleware outside the innermost visibility runs.
|
|
428
|
+
const visible = (method, target) => invocation => {
|
|
429
|
+
const middleware = middlewareStack(localMiddleware, globalMiddleware);
|
|
430
|
+
const innermost = middleware.findIndex(fn => gates.has(fn));
|
|
431
|
+
if (innermost === -1) {
|
|
432
|
+
return Effect.succeed(true);
|
|
433
|
+
}
|
|
434
|
+
return runMiddleware(Effect.void, middleware.slice(innermost), invocation, {
|
|
435
|
+
method,
|
|
436
|
+
target,
|
|
437
|
+
payload: undefined
|
|
438
|
+
}).pipe(Effect.as(true), catchHidden(() => Effect.succeed(false)));
|
|
439
|
+
};
|
|
440
|
+
return {
|
|
441
|
+
invoke,
|
|
442
|
+
visible
|
|
443
|
+
};
|
|
444
|
+
};
|
|
445
|
+
// Applies the `EnabledWhen` annotation of a registration.
|
|
446
|
+
const isEnabled = annotations => {
|
|
447
|
+
const enabledWhen = Context.getOrUndefined(annotations, EnabledWhen);
|
|
448
|
+
return profile => enabledWhen === undefined || enabledWhen({
|
|
449
|
+
protocolVersion: profile.protocolVersion,
|
|
450
|
+
capabilities: profile.clientCapabilities,
|
|
451
|
+
clientInfo: profile.clientInfo
|
|
452
|
+
});
|
|
453
|
+
};
|
|
454
|
+
const rejectedError = rejected => Effect.fail(rejected.error);
|
|
120
455
|
/**
|
|
121
456
|
* Service that stores and serves an MCP server's registered tools, resources,
|
|
122
457
|
* prompts, completions, and outgoing notifications.
|
|
@@ -144,6 +479,7 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
144
479
|
const resourceTemplates = [];
|
|
145
480
|
const prompts = [];
|
|
146
481
|
const notificationsQueue = yield* Queue.make();
|
|
482
|
+
const globalMiddleware = [];
|
|
147
483
|
const notificationDelivery = {
|
|
148
484
|
consumers: 0,
|
|
149
485
|
listChangeRevision: 0,
|
|
@@ -233,18 +569,22 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
233
569
|
} else {
|
|
234
570
|
tools[existingIndex] = options;
|
|
235
571
|
}
|
|
236
|
-
const
|
|
572
|
+
const {
|
|
573
|
+
invoke,
|
|
574
|
+
visible
|
|
575
|
+
} = makeInvoke(options.services, globalMiddleware);
|
|
237
576
|
yield* internalCore.tools.register({
|
|
238
577
|
descriptor: new McpTool({
|
|
239
578
|
...options.tool,
|
|
240
579
|
title: options.tool.title ?? options.tool.annotations?.title
|
|
241
580
|
}),
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
581
|
+
visible: visible("tools/list", options.tool.name),
|
|
582
|
+
isVisible: isEnabled(options.annotations),
|
|
583
|
+
handle: (call, invocation) => invoke(options.handle(call.arguments), invocation, {
|
|
584
|
+
method: "tools/call",
|
|
585
|
+
target: call.name,
|
|
586
|
+
payload: call
|
|
587
|
+
}).pipe(Effect.catchTags({
|
|
248
588
|
InternalError: error => Effect.fail(new McpCore.ToolExecutionError({
|
|
249
589
|
name: options.tool.name,
|
|
250
590
|
message: error.message
|
|
@@ -259,9 +599,9 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
259
599
|
}),
|
|
260
600
|
callTool: Effect.fnUntraced(function* (request) {
|
|
261
601
|
const client = yield* McpServerClient;
|
|
262
|
-
const result = yield* internalCore.tools.call(request, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.
|
|
602
|
+
const result = yield* internalCore.tools.call(request, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.catch(error => error._tag === "RequestRejected" ? rejectedError(error) : Effect.fail(new InvalidParams({
|
|
263
603
|
message: error._tag === "ToolNotFound" ? `Tool '${error.name}' not found` : error.message
|
|
264
|
-
})));
|
|
604
|
+
}))));
|
|
265
605
|
if (result._tag === "InputRequired") {
|
|
266
606
|
return yield* new InvalidParams({
|
|
267
607
|
message: "Client input is not supported by this MCP protocol"
|
|
@@ -284,17 +624,21 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
284
624
|
} else {
|
|
285
625
|
resources[existingIndex] = options;
|
|
286
626
|
}
|
|
627
|
+
const {
|
|
628
|
+
invoke,
|
|
629
|
+
visible
|
|
630
|
+
} = makeInvoke(options.services, globalMiddleware);
|
|
287
631
|
yield* internalCore.resources.register({
|
|
288
632
|
descriptor: options.resource,
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
633
|
+
visible: visible("resources/list", options.resource.uri),
|
|
634
|
+
isVisible: isEnabled(options.annotations),
|
|
635
|
+
read: invocation => invoke(options.handle, invocation, {
|
|
636
|
+
method: "resources/read",
|
|
637
|
+
target: options.resource.uri,
|
|
638
|
+
payload: {
|
|
639
|
+
uri: options.resource.uri
|
|
640
|
+
}
|
|
641
|
+
})
|
|
298
642
|
});
|
|
299
643
|
yield* notifications.client["notifications/resources/list_changed"]({});
|
|
300
644
|
}),
|
|
@@ -303,6 +647,7 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
303
647
|
completions,
|
|
304
648
|
handle,
|
|
305
649
|
routerPath,
|
|
650
|
+
services,
|
|
306
651
|
template
|
|
307
652
|
}) {
|
|
308
653
|
const existingIndex = resourceTemplates.findIndex(({
|
|
@@ -319,18 +664,16 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
319
664
|
annotations
|
|
320
665
|
};
|
|
321
666
|
}
|
|
667
|
+
const {
|
|
668
|
+
invoke,
|
|
669
|
+
visible
|
|
670
|
+
} = makeInvoke(services, globalMiddleware);
|
|
322
671
|
const templateMatcher = makeUriMatcher();
|
|
323
672
|
templateMatcher.add(routerPath, true);
|
|
324
673
|
yield* internalCore.resources.registerTemplate({
|
|
325
674
|
descriptor: template,
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
return enabledWhen === undefined || enabledWhen({
|
|
329
|
-
protocolVersion: profile.protocolVersion,
|
|
330
|
-
capabilities: profile.clientCapabilities,
|
|
331
|
-
clientInfo: profile.clientInfo
|
|
332
|
-
});
|
|
333
|
-
},
|
|
675
|
+
visible: visible("resources/templates/list", template.uriTemplate),
|
|
676
|
+
isVisible: isEnabled(annotations),
|
|
334
677
|
match: uri => {
|
|
335
678
|
const match = templateMatcher.find(uri);
|
|
336
679
|
if (match === undefined) {
|
|
@@ -342,10 +685,20 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
342
685
|
}
|
|
343
686
|
return params;
|
|
344
687
|
},
|
|
345
|
-
read: (uri, params, invocation) =>
|
|
688
|
+
read: (uri, params, invocation) => invoke(handle(uri, Array.from(params)), invocation, {
|
|
689
|
+
method: "resources/read",
|
|
690
|
+
target: uri,
|
|
691
|
+
payload: {
|
|
692
|
+
uri
|
|
693
|
+
}
|
|
694
|
+
})
|
|
346
695
|
});
|
|
347
696
|
for (const [param, handle] of Object.entries(completions)) {
|
|
348
|
-
yield* internalCore.completions.register(`resource/${template.uriTemplate}/${param}`, (request, invocation) =>
|
|
697
|
+
yield* internalCore.completions.register(`resource/${template.uriTemplate}/${param}`, (request, invocation) => invoke(handle(request.argument.value, request.context), invocation, {
|
|
698
|
+
method: "completion/complete",
|
|
699
|
+
target: template.uriTemplate,
|
|
700
|
+
payload: request
|
|
701
|
+
}).pipe(Effect.map(result => ({
|
|
349
702
|
values: result.completion.values,
|
|
350
703
|
total: result.completion.total,
|
|
351
704
|
hasMore: result.completion.hasMore,
|
|
@@ -356,9 +709,12 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
356
709
|
}),
|
|
357
710
|
findResource: Effect.fnUntraced(function* (uri) {
|
|
358
711
|
const client = yield* McpServerClient;
|
|
359
|
-
return yield* internalCore.resources.read(uri, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.
|
|
360
|
-
|
|
361
|
-
|
|
712
|
+
return yield* internalCore.resources.read(uri, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.catchTags({
|
|
713
|
+
ResourceNotFound: error => Effect.fail(new InvalidParams({
|
|
714
|
+
message: `Resource '${error.uri}' not found`
|
|
715
|
+
})),
|
|
716
|
+
RequestRejected: rejectedError
|
|
717
|
+
}));
|
|
362
718
|
}),
|
|
363
719
|
get prompts() {
|
|
364
720
|
return prompts;
|
|
@@ -372,20 +728,29 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
372
728
|
} else {
|
|
373
729
|
prompts[existingIndex] = options;
|
|
374
730
|
}
|
|
731
|
+
const {
|
|
732
|
+
invoke,
|
|
733
|
+
visible
|
|
734
|
+
} = makeInvoke(options.services, globalMiddleware);
|
|
375
735
|
yield* internalCore.prompts.register({
|
|
376
736
|
descriptor: options.prompt,
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
737
|
+
visible: visible("prompts/list", options.prompt.name),
|
|
738
|
+
isVisible: isEnabled(options.annotations),
|
|
739
|
+
get: (params, invocation) => invoke(options.handle(params), invocation, {
|
|
740
|
+
method: "prompts/get",
|
|
741
|
+
target: options.prompt.name,
|
|
742
|
+
payload: {
|
|
743
|
+
name: options.prompt.name,
|
|
744
|
+
arguments: params
|
|
745
|
+
}
|
|
746
|
+
}).pipe(Effect.map(result => Predicate.isTagged(result, "InputRequired") ? McpCore.OperationOutcome.InputRequired(result) : McpCore.OperationOutcome.Complete(result)))
|
|
386
747
|
});
|
|
387
748
|
for (const [param, handle] of Object.entries(options.completions)) {
|
|
388
|
-
yield* internalCore.completions.register(`prompt/${options.prompt.name}/${param}`, (request, invocation) =>
|
|
749
|
+
yield* internalCore.completions.register(`prompt/${options.prompt.name}/${param}`, (request, invocation) => invoke(handle(request.argument.value, request.context), invocation, {
|
|
750
|
+
method: "completion/complete",
|
|
751
|
+
target: options.prompt.name,
|
|
752
|
+
payload: request
|
|
753
|
+
}).pipe(Effect.map(result => ({
|
|
389
754
|
values: result.completion.values,
|
|
390
755
|
total: result.completion.total,
|
|
391
756
|
hasMore: result.completion.hasMore,
|
|
@@ -399,9 +764,12 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
399
764
|
name
|
|
400
765
|
}) {
|
|
401
766
|
const client = yield* McpServerClient;
|
|
402
|
-
const outcome = yield* internalCore.prompts.get(name, params ?? {}, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.
|
|
403
|
-
|
|
404
|
-
|
|
767
|
+
const outcome = yield* internalCore.prompts.get(name, params ?? {}, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.catchTags({
|
|
768
|
+
PromptNotFound: () => new InvalidParams({
|
|
769
|
+
message: `Prompt '${name}' not found`
|
|
770
|
+
}),
|
|
771
|
+
RequestRejected: rejectedError
|
|
772
|
+
}));
|
|
405
773
|
return outcome._tag === "Complete" ? outcome.value : yield* new InvalidParams({
|
|
406
774
|
message: "Client input is not supported by this MCP protocol"
|
|
407
775
|
});
|
|
@@ -419,7 +787,7 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
419
787
|
},
|
|
420
788
|
argument: complete.argument,
|
|
421
789
|
context: complete.context
|
|
422
|
-
}, McpProtocolInternal.invocationFromClient(client));
|
|
790
|
+
}, McpProtocolInternal.invocationFromClient(client)).pipe(Effect.catchTag("RequestRejected", rejectedError));
|
|
423
791
|
return {
|
|
424
792
|
_meta: result.metadata,
|
|
425
793
|
completion: {
|
|
@@ -433,12 +801,19 @@ export class McpServer extends /*#__PURE__*/Context.Service()("effect/ai/McpServ
|
|
|
433
801
|
internalState.set(service, {
|
|
434
802
|
core: internalCore,
|
|
435
803
|
notifications: notificationsQueue,
|
|
436
|
-
notificationDelivery
|
|
804
|
+
notificationDelivery,
|
|
805
|
+
globalMiddleware
|
|
437
806
|
});
|
|
438
807
|
return service;
|
|
439
808
|
});
|
|
440
809
|
/**
|
|
441
|
-
* Layer that provides the MCP server
|
|
810
|
+
* Layer that provides the MCP server service.
|
|
811
|
+
*
|
|
812
|
+
* **Details**
|
|
813
|
+
*
|
|
814
|
+
* It doesn't run a transport or discharge request-level dependencies. Use it
|
|
815
|
+
* to call registrations in process, providing their request-level
|
|
816
|
+
* dependencies with MCP middleware.
|
|
442
817
|
*
|
|
443
818
|
* @stability unstable
|
|
444
819
|
* @since 4.0.0
|
|
@@ -452,6 +827,26 @@ const cancelledResponses = /*#__PURE__*/new WeakMap();
|
|
|
452
827
|
const httpPostResponses = /*#__PURE__*/new WeakMap();
|
|
453
828
|
const requestKey = requestId => `${typeof requestId}:${requestId}`;
|
|
454
829
|
class McpClientKey extends Data.Class {}
|
|
830
|
+
// Converts each hint to the wire's nonnegative integer `ttlMs` once, when the server is built.
|
|
831
|
+
const normalizeCacheHints = cacheHints => {
|
|
832
|
+
if (cacheHints === undefined) return Effect.succeed(undefined);
|
|
833
|
+
const normalized = {};
|
|
834
|
+
for (const [name, hint] of Object.entries(cacheHints)) {
|
|
835
|
+
if (hint === undefined) continue;
|
|
836
|
+
const ttlMs = Option.match(Duration.fromInput(hint.ttl), {
|
|
837
|
+
onNone: () => NaN,
|
|
838
|
+
onSome: ttl => Math.floor(Duration.toMillis(ttl))
|
|
839
|
+
});
|
|
840
|
+
if (!Number.isSafeInteger(ttlMs) || ttlMs < 0 || hint.cacheScope !== "private") {
|
|
841
|
+
return Effect.fail(new Cause.IllegalArgumentError(`McpServer cacheHints.${name} must have a finite, nonnegative ttl and a "private" cacheScope`));
|
|
842
|
+
}
|
|
843
|
+
normalized[name] = {
|
|
844
|
+
ttlMs,
|
|
845
|
+
cacheScope: "private"
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
return Effect.succeed(normalized);
|
|
849
|
+
};
|
|
455
850
|
/**
|
|
456
851
|
* Runs an MCP server over the current `RpcServer.Protocol`.
|
|
457
852
|
*
|
|
@@ -466,9 +861,13 @@ class McpClientKey extends Data.Class {}
|
|
|
466
861
|
* @since 4.0.0
|
|
467
862
|
*/
|
|
468
863
|
export const run = /*#__PURE__*/Effect.fnUntraced(function* (options) {
|
|
864
|
+
const cacheHints = yield* normalizeCacheHints(options.cacheHints);
|
|
469
865
|
const runtimeOption = yield* Effect.serviceOption(McpRuntime.ServerRuntime);
|
|
470
866
|
const runtime = Option.isSome(runtimeOption) ? runtimeOption.value : yield* McpRuntime.make(options.protocols);
|
|
471
|
-
return yield* runWithRuntime(
|
|
867
|
+
return yield* runWithRuntime({
|
|
868
|
+
...options,
|
|
869
|
+
cacheHints
|
|
870
|
+
}, runtime, "custom");
|
|
472
871
|
});
|
|
473
872
|
const runWithRuntime = /*#__PURE__*/Effect.fnUntraced(function* (options, runtime, transport, requestScoped) {
|
|
474
873
|
const protocol = yield* RpcServer.Protocol;
|
|
@@ -975,7 +1374,7 @@ const runWithRuntime = /*#__PURE__*/Effect.fnUntraced(function* (options, runtim
|
|
|
975
1374
|
if (requestContext?.clientId !== clientId || !isLoggingLevel(level) || McpSchema.LoggingLevel.literals.indexOf(notification.level) < McpSchema.LoggingLevel.literals.indexOf(level)) {
|
|
976
1375
|
return;
|
|
977
1376
|
}
|
|
978
|
-
} else if (!runtime.canDeliver(clientId, (requestContext?.clientId === clientId ? requestHeaders : undefined) ?? clientStates.get(clientId)?.sessionHeaders ?? Headers.empty, notification, defaultLogLevel)) {
|
|
1377
|
+
} else if (!runtime.canDeliver(clientId, (requestContext?.clientId === clientId ? requestHeaders : undefined) ?? clientStates.get(clientId)?.sessionHeaders ?? Headers.empty, notification, defaultLogLevel, listChangeRevision)) {
|
|
979
1378
|
return;
|
|
980
1379
|
}
|
|
981
1380
|
const rpc = selectedProtocol.serverNotificationRpcs.requests.get(projected.tag);
|
|
@@ -1028,6 +1427,11 @@ const runWithRuntime = /*#__PURE__*/Effect.fnUntraced(function* (options, runtim
|
|
|
1028
1427
|
* `McpServer.layer`, so registration layers can use the `McpServer` service
|
|
1029
1428
|
* while the server is running.
|
|
1030
1429
|
*
|
|
1430
|
+
* Pass registration layers as `registrations` to build them before the server
|
|
1431
|
+
* reads its first request. The transport discharges the request-level
|
|
1432
|
+
* dependencies it supplies (see `ProvidedServices`); any other `McpRequest`
|
|
1433
|
+
* marker stays in the layer's requirements and must be met by MCP middleware.
|
|
1434
|
+
*
|
|
1031
1435
|
* **Gotchas**
|
|
1032
1436
|
*
|
|
1033
1437
|
* Unlike `layerStdio` and `layerHttp`, this layer does not install a concrete
|
|
@@ -1043,9 +1447,13 @@ const runWithRuntime = /*#__PURE__*/Effect.fnUntraced(function* (options, runtim
|
|
|
1043
1447
|
*/
|
|
1044
1448
|
export const layer = options => layerWithRuntime(options, "custom").pipe(Layer.provide(McpRuntime.layer(options.protocols)));
|
|
1045
1449
|
const layerWithRuntime = (options, transport) => Layer.effectDiscard(Effect.gen(function* () {
|
|
1450
|
+
const cacheHints = yield* normalizeCacheHints(options.cacheHints);
|
|
1046
1451
|
const runtime = yield* McpRuntime.ServerRuntime;
|
|
1047
|
-
yield* Effect.forkScoped(runWithRuntime(
|
|
1048
|
-
|
|
1452
|
+
yield* Effect.forkScoped(runWithRuntime({
|
|
1453
|
+
...options,
|
|
1454
|
+
cacheHints
|
|
1455
|
+
}, runtime, transport));
|
|
1456
|
+
})).pipe(Layer.provide(options.registrations ?? Layer.empty), Layer.provideMerge(McpServer.layer));
|
|
1049
1457
|
/**
|
|
1050
1458
|
* Creates a layer that runs an MCP server over standard input and output.
|
|
1051
1459
|
*
|
|
@@ -1061,6 +1469,11 @@ const layerWithRuntime = (options, transport) => Layer.effectDiscard(Effect.gen(
|
|
|
1061
1469
|
* `McpRequestContext` and legacy `McpServerClient` services to handlers, and
|
|
1062
1470
|
* requires `Stdio`.
|
|
1063
1471
|
*
|
|
1472
|
+
* Pass registration layers as `registrations` to build them before the server
|
|
1473
|
+
* reads its first request. The transport discharges the request-level
|
|
1474
|
+
* dependencies it supplies (see `ProvidedServices`); any other `McpRequest`
|
|
1475
|
+
* marker stays in the layer's requirements and must be met by MCP middleware.
|
|
1476
|
+
*
|
|
1064
1477
|
* @see {@link layer} for running over an existing `RpcServer.Protocol`
|
|
1065
1478
|
* @see {@link layerHttp} for the single-endpoint HTTP transport
|
|
1066
1479
|
*
|
|
@@ -1161,6 +1574,13 @@ const mcpStdioSerialization = protocols => {
|
|
|
1161
1574
|
* serverless hosts where execution must belong to each request, use
|
|
1162
1575
|
* `layerHttpRequestScoped` instead.
|
|
1163
1576
|
*
|
|
1577
|
+
* Pass registration layers as `registrations` to build them before the
|
|
1578
|
+
* endpoint serves its first request. The transport discharges the
|
|
1579
|
+
* request-level dependencies it supplies (see `ProvidedServices`) and converts
|
|
1580
|
+
* the remaining `McpRequest` markers into `HttpRouter.Request` markers, so
|
|
1581
|
+
* `HttpRouter.middleware` can provide them, for example to authenticate the
|
|
1582
|
+
* request and resolve the current user.
|
|
1583
|
+
*
|
|
1164
1584
|
* `layerHttp` always implements the single-endpoint Streamable HTTP topology.
|
|
1165
1585
|
* Using `v2024_11_05` here is a custom compatibility transport for that
|
|
1166
1586
|
* revision's schema. It does not implement the historical two-endpoint
|
|
@@ -1210,6 +1630,10 @@ export const layerHttp = options => {
|
|
|
1210
1630
|
* Configuring a sessionful protocol through an untyped caller fails layer
|
|
1211
1631
|
* construction with `IllegalArgumentError`.
|
|
1212
1632
|
*
|
|
1633
|
+
* Registrations passed as `registrations` are built once, before the routes
|
|
1634
|
+
* are added, and shared by every POST. Remaining `McpRequest` markers become
|
|
1635
|
+
* `HttpRouter.Request` markers, as with `layerHttp`.
|
|
1636
|
+
*
|
|
1213
1637
|
* @see {@link layerHttp} for the long-lived HTTP transport and HTTP admission policy
|
|
1214
1638
|
*
|
|
1215
1639
|
* @stability unstable
|
|
@@ -1222,6 +1646,10 @@ export const layerHttpRequestScoped = options => Layer.effectDiscard(Effect.gen(
|
|
|
1222
1646
|
if (stateful !== undefined) {
|
|
1223
1647
|
return yield* new Cause.IllegalArgumentError(`McpServer.layerHttpRequestScoped does not support the sessionful MCP protocol ${stateful.protocolVersion}`);
|
|
1224
1648
|
}
|
|
1649
|
+
const serverOptions = {
|
|
1650
|
+
...options,
|
|
1651
|
+
cacheHints: yield* normalizeCacheHints(options.cacheHints)
|
|
1652
|
+
};
|
|
1225
1653
|
const server = yield* McpServer;
|
|
1226
1654
|
const {
|
|
1227
1655
|
core,
|
|
@@ -1235,7 +1663,7 @@ export const layerHttpRequestScoped = options => Layer.effectDiscard(Effect.gen(
|
|
|
1235
1663
|
subscribeServerNotifications: Effect.die("Subscriptions are disabled for request-scoped MCP servers"),
|
|
1236
1664
|
getListChangeRevision: () => notificationDelivery.listChangeRevision,
|
|
1237
1665
|
defaultLogLevel: yield* CurrentLogLevel,
|
|
1238
|
-
serverInfo:
|
|
1666
|
+
serverInfo: serverOptions
|
|
1239
1667
|
});
|
|
1240
1668
|
yield* Effect.acquireRelease(Effect.sync(() => {
|
|
1241
1669
|
notificationDelivery.requestEndpoints++;
|
|
@@ -1250,7 +1678,7 @@ export const layerHttpRequestScoped = options => Layer.effectDiscard(Effect.gen(
|
|
|
1250
1678
|
protocol
|
|
1251
1679
|
} = yield* RpcServer.makeProtocolWithHttpEffect().pipe(Effect.provideService(RpcSerialization.RpcSerialization, mcpHttpSerialization));
|
|
1252
1680
|
const notifications = yield* Queue.make();
|
|
1253
|
-
yield* runWithRuntime(
|
|
1681
|
+
yield* runWithRuntime(serverOptions, runtime, "http", {
|
|
1254
1682
|
notifications,
|
|
1255
1683
|
handlers
|
|
1256
1684
|
}).pipe(Effect.provideService(RpcServer.Protocol, protocol), Effect.provideService(McpServer, server), Effect.forkScoped({
|
|
@@ -1258,7 +1686,7 @@ export const layerHttpRequestScoped = options => Layer.effectDiscard(Effect.gen(
|
|
|
1258
1686
|
}));
|
|
1259
1687
|
return yield* Effect.provideService(httpEffect, RequestNotificationQueue, notifications);
|
|
1260
1688
|
}));
|
|
1261
|
-
})).pipe(Layer.provideMerge(McpServer.layer), Layer.provide(McpRuntime.layer(options.protocols)));
|
|
1689
|
+
})).pipe(Layer.provide(options.registrations ?? Layer.empty), Layer.provideMerge(McpServer.layer), Layer.provide(McpRuntime.layer(options.protocols)));
|
|
1262
1690
|
const layerMcpProtocolHttp = options => Layer.effect(RpcServer.Protocol)(Effect.gen(function* () {
|
|
1263
1691
|
const {
|
|
1264
1692
|
httpEffect,
|
|
@@ -1480,6 +1908,13 @@ const toolResultContent = encoded => encoded === undefined ? [] : [{
|
|
|
1480
1908
|
/**
|
|
1481
1909
|
* Registers a `Toolkit` with the `McpServer`.
|
|
1482
1910
|
*
|
|
1911
|
+
* **Details**
|
|
1912
|
+
*
|
|
1913
|
+
* The MCP middleware in the current context, provided with
|
|
1914
|
+
* `Effect.provide(middleware.layer)`, runs around every call to the toolkit.
|
|
1915
|
+
*
|
|
1916
|
+
* @see {@link ToolkitRequirements} for which services are request-level
|
|
1917
|
+
*
|
|
1483
1918
|
* @stability unstable
|
|
1484
1919
|
* @category handlers
|
|
1485
1920
|
* @since 4.0.0
|
|
@@ -1500,12 +1935,11 @@ export const registerToolkit = /*#__PURE__*/Effect.fnUntraced(function* (toolkit
|
|
|
1500
1935
|
}
|
|
1501
1936
|
return Context.makeUnsafe(services);
|
|
1502
1937
|
}));
|
|
1503
|
-
const services =
|
|
1504
|
-
const reportCause = cause => Effect.provideContext(ErrorReporter.report(cause), services);
|
|
1938
|
+
const services = yield* Effect.context();
|
|
1505
1939
|
// Interruption propagates; anything else is logged, reported and scrubbed.
|
|
1506
1940
|
const internalToolError = cause => {
|
|
1507
1941
|
const failure = Cause.findFail(cause);
|
|
1508
|
-
return Result.isFailure(failure) && !Cause.hasDies(cause) ? Effect.failCause(failure.failure) : Effect.logError(cause).pipe(Effect.andThen(
|
|
1942
|
+
return Result.isFailure(failure) && !Cause.hasDies(cause) ? Effect.failCause(failure.failure) : Effect.logError(cause).pipe(Effect.andThen(ErrorReporter.report(cause)), Effect.as(toolErrorResult(INTERNAL_TOOL_ERROR_MESSAGE)));
|
|
1509
1943
|
};
|
|
1510
1944
|
const registrations = [];
|
|
1511
1945
|
for (const tool of Object.values(built.tools)) {
|
|
@@ -1570,8 +2004,9 @@ export const registerToolkit = /*#__PURE__*/Effect.fnUntraced(function* (toolkit
|
|
|
1570
2004
|
isError: result.isFailure,
|
|
1571
2005
|
structuredContent: result.isFailure ? undefined : result.encodedResult,
|
|
1572
2006
|
content: toolResultContent(result.encodedResult)
|
|
1573
|
-
}))), Effect.catchCause(handleCause)
|
|
1574
|
-
}
|
|
2007
|
+
}))), Effect.catchCause(handleCause));
|
|
2008
|
+
},
|
|
2009
|
+
services
|
|
1575
2010
|
});
|
|
1576
2011
|
}
|
|
1577
2012
|
for (const registration of registrations) {
|
|
@@ -1598,13 +2033,31 @@ const toolJsonSchema = (schema, strict) => {
|
|
|
1598
2033
|
};
|
|
1599
2034
|
};
|
|
1600
2035
|
/**
|
|
1601
|
-
*
|
|
2036
|
+
* Creates a layer that registers a `Toolkit` with the `McpServer`.
|
|
2037
|
+
*
|
|
2038
|
+
* **Details**
|
|
2039
|
+
*
|
|
2040
|
+
* The layer requires `McpServer`. Pass it to a transport through the
|
|
2041
|
+
* `registrations` option, or provide the transport layer to it.
|
|
2042
|
+
*
|
|
2043
|
+
* @see {@link ToolkitRequirements} for which services are request-level
|
|
1602
2044
|
*
|
|
1603
2045
|
* @stability unstable
|
|
1604
2046
|
* @category layers
|
|
1605
2047
|
* @since 4.0.0
|
|
1606
2048
|
*/
|
|
1607
|
-
export const toolkit = toolkit => Layer.effectDiscard(registerToolkit(toolkit))
|
|
2049
|
+
export const toolkit = toolkit => Layer.effectDiscard(registerToolkit(toolkit));
|
|
2050
|
+
// Leave defects and interruption to makeInvoke; convert only expected failures.
|
|
2051
|
+
const handlerFailureToInternalError = cause => Cause.hasDies(cause) || Cause.hasInterrupts(cause) ? Effect.failCause(cause) : Effect.fail(new InternalError({
|
|
2052
|
+
message: Cause.prettyErrors(cause)[0].message
|
|
2053
|
+
}));
|
|
2054
|
+
const completionHandler = (handle, encodeValues) => (input, context) => handle(input, context).pipe(Effect.flatMap(encodeValues), Effect.map(values => ({
|
|
2055
|
+
completion: {
|
|
2056
|
+
values: values,
|
|
2057
|
+
total: values.length,
|
|
2058
|
+
hasMore: false
|
|
2059
|
+
}
|
|
2060
|
+
})), Effect.catchCause(handlerFailureToInternalError));
|
|
1608
2061
|
/**
|
|
1609
2062
|
* Registers an MCP resource or resource template from an Effect program.
|
|
1610
2063
|
*
|
|
@@ -1618,19 +2071,15 @@ export const registerResource = function () {
|
|
|
1618
2071
|
if (arguments.length === 1) {
|
|
1619
2072
|
const options = arguments[0];
|
|
1620
2073
|
return Effect.gen(function* () {
|
|
1621
|
-
const services =
|
|
2074
|
+
const services = yield* Effect.context();
|
|
1622
2075
|
const registry = yield* McpServer;
|
|
1623
2076
|
yield* registry.addResource({
|
|
1624
2077
|
resource: new Resource({
|
|
1625
2078
|
...options,
|
|
1626
2079
|
annotations: options
|
|
1627
2080
|
}),
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
return Effect.fail(new InternalError({
|
|
1631
|
-
message: prettyError.message
|
|
1632
|
-
}));
|
|
1633
|
-
})),
|
|
2081
|
+
services,
|
|
2082
|
+
handle: options.content.pipe(Effect.map(content => resolveResourceContent(options.uri, content)), Effect.catchCause(handlerFailureToInternalError)),
|
|
1634
2083
|
annotations: options.annotations ?? Context.empty()
|
|
1635
2084
|
});
|
|
1636
2085
|
});
|
|
@@ -1642,7 +2091,7 @@ export const registerResource = function () {
|
|
|
1642
2091
|
uriPath
|
|
1643
2092
|
} = compileUriTemplate(...arguments);
|
|
1644
2093
|
return Effect.fnUntraced(function* (options) {
|
|
1645
|
-
const services =
|
|
2094
|
+
const services = yield* Effect.context();
|
|
1646
2095
|
const registry = yield* McpServer;
|
|
1647
2096
|
const decode = Schema.decodeUnknownEffect(schema);
|
|
1648
2097
|
const template = new ResourceTemplate({
|
|
@@ -1652,41 +2101,32 @@ export const registerResource = function () {
|
|
|
1652
2101
|
});
|
|
1653
2102
|
const completions = Object.create(null);
|
|
1654
2103
|
for (const [param, handle] of Object.entries(options.completion ?? {})) {
|
|
1655
|
-
|
|
1656
|
-
const handler = (input, context) => handle(input, context).pipe(Effect.flatMap(encodeArray), Effect.map(values => ({
|
|
1657
|
-
completion: {
|
|
1658
|
-
values: values,
|
|
1659
|
-
total: values.length,
|
|
1660
|
-
hasMore: false
|
|
1661
|
-
}
|
|
1662
|
-
})), Effect.catchCause(cause => {
|
|
1663
|
-
const prettyError = Cause.prettyErrors(cause)[0];
|
|
1664
|
-
return Effect.fail(new InternalError({
|
|
1665
|
-
message: prettyError.message
|
|
1666
|
-
}));
|
|
1667
|
-
}), Effect.provideContext(services));
|
|
1668
|
-
completions[param] = handler;
|
|
2104
|
+
completions[param] = completionHandler(handle, Schema.encodeUnknownEffect(Schema.Array(params[param])));
|
|
1669
2105
|
}
|
|
1670
2106
|
yield* registry.addResourceTemplate({
|
|
1671
2107
|
template,
|
|
1672
2108
|
routerPath,
|
|
1673
2109
|
completions,
|
|
2110
|
+
services,
|
|
1674
2111
|
annotations: options.annotations ?? Context.empty(),
|
|
1675
2112
|
handle: (uri, params) => decode(params).pipe(Effect.mapError(error => new InvalidParams({
|
|
1676
2113
|
message: error.message
|
|
1677
|
-
})), Effect.flatMap(params => options.content(uri, ...params).pipe(Effect.map(content => resolveResourceContent(uri, content)), Effect.catchCause(
|
|
1678
|
-
const prettyError = Cause.prettyErrors(cause)[0];
|
|
1679
|
-
return Effect.fail(new InternalError({
|
|
1680
|
-
message: prettyError.message
|
|
1681
|
-
}));
|
|
1682
|
-
}))), Effect.provideContext(services))
|
|
2114
|
+
})), Effect.flatMap(params => options.content(uri, ...params).pipe(Effect.map(content => resolveResourceContent(uri, content)), Effect.catchCause(handlerFailureToInternalError))))
|
|
1683
2115
|
});
|
|
1684
2116
|
});
|
|
1685
2117
|
};
|
|
1686
2118
|
/**
|
|
1687
2119
|
* Creates a layer that registers an MCP resource or resource template.
|
|
1688
2120
|
*
|
|
2121
|
+
* **Details**
|
|
2122
|
+
*
|
|
2123
|
+
* Services read by the content and completion handlers are request-level, so
|
|
2124
|
+
* providing them with `Layer.provide` doesn't satisfy them. Read
|
|
2125
|
+
* construction-time services in an enclosing `Layer.unwrap` and close over
|
|
2126
|
+
* them, and provide per-request services with MCP middleware.
|
|
2127
|
+
*
|
|
1689
2128
|
* @see {@link registerResource} for the Effect-level resource registration API
|
|
2129
|
+
* @see {@link middleware} for providing request-level dependencies
|
|
1690
2130
|
*
|
|
1691
2131
|
* @stability unstable
|
|
1692
2132
|
* @category layers
|
|
@@ -1694,10 +2134,10 @@ export const registerResource = function () {
|
|
|
1694
2134
|
*/
|
|
1695
2135
|
export const resource = function () {
|
|
1696
2136
|
if (arguments.length === 1) {
|
|
1697
|
-
return Layer.effectDiscard(registerResource(arguments[0]))
|
|
2137
|
+
return Layer.effectDiscard(registerResource(arguments[0]));
|
|
1698
2138
|
}
|
|
1699
2139
|
const register = registerResource(...arguments);
|
|
1700
|
-
return options => Layer.effectDiscard(register(options))
|
|
2140
|
+
return options => Layer.effectDiscard(register(options));
|
|
1701
2141
|
};
|
|
1702
2142
|
/**
|
|
1703
2143
|
* Registers an MCP prompt from an Effect program.
|
|
@@ -1733,36 +2173,19 @@ export const registerPrompt = options => {
|
|
|
1733
2173
|
const completion = options.completion ?? {};
|
|
1734
2174
|
return Effect.gen(function* () {
|
|
1735
2175
|
const registry = yield* McpServer;
|
|
1736
|
-
const services =
|
|
2176
|
+
const services = yield* Effect.context();
|
|
1737
2177
|
const completions = Object.create(null);
|
|
1738
2178
|
for (const [param, handle] of Object.entries(completion)) {
|
|
1739
|
-
|
|
1740
|
-
const handler = (input, context) => handle(input, context).pipe(Effect.flatMap(encodeArray), Effect.map(values => ({
|
|
1741
|
-
completion: {
|
|
1742
|
-
values: values,
|
|
1743
|
-
total: values.length,
|
|
1744
|
-
hasMore: false
|
|
1745
|
-
}
|
|
1746
|
-
})), Effect.catchCause(cause => {
|
|
1747
|
-
const prettyError = Cause.prettyErrors(cause)[0];
|
|
1748
|
-
return Effect.fail(new InternalError({
|
|
1749
|
-
message: prettyError.message
|
|
1750
|
-
}));
|
|
1751
|
-
}), Effect.provide(services));
|
|
1752
|
-
completions[param] = handler;
|
|
2179
|
+
completions[param] = completionHandler(handle, Schema.encodeUnknownEffect(Schema.Array(props[param])));
|
|
1753
2180
|
}
|
|
1754
2181
|
yield* registry.addPrompt({
|
|
1755
2182
|
prompt,
|
|
1756
2183
|
completions,
|
|
2184
|
+
services,
|
|
1757
2185
|
annotations: options.annotations ?? Context.empty(),
|
|
1758
2186
|
handle: params => decode(params).pipe(Effect.mapError(error => new InvalidParams({
|
|
1759
2187
|
message: error.message
|
|
1760
|
-
})), Effect.flatMap(params => options.content(params).pipe(Effect.catchCause(
|
|
1761
|
-
const prettyError = Cause.prettyErrors(cause)[0];
|
|
1762
|
-
return Effect.fail(new InternalError({
|
|
1763
|
-
message: prettyError.message
|
|
1764
|
-
}));
|
|
1765
|
-
}))), Effect.map(messages => {
|
|
2188
|
+
})), Effect.flatMap(params => options.content(params).pipe(Effect.catchCause(handlerFailureToInternalError))), Effect.map(messages => {
|
|
1766
2189
|
messages = typeof messages === "string" ? [{
|
|
1767
2190
|
role: "user",
|
|
1768
2191
|
content: TextContent.make({
|
|
@@ -1773,20 +2196,28 @@ export const registerPrompt = options => {
|
|
|
1773
2196
|
messages,
|
|
1774
2197
|
description: prompt.description
|
|
1775
2198
|
});
|
|
1776
|
-
})
|
|
2199
|
+
}))
|
|
1777
2200
|
});
|
|
1778
2201
|
});
|
|
1779
2202
|
};
|
|
1780
2203
|
/**
|
|
1781
2204
|
* Creates a layer that registers an MCP prompt.
|
|
1782
2205
|
*
|
|
2206
|
+
* **Details**
|
|
2207
|
+
*
|
|
2208
|
+
* Services read by the content and completion handlers are request-level, so
|
|
2209
|
+
* providing them with `Layer.provide` doesn't satisfy them. Read
|
|
2210
|
+
* construction-time services in an enclosing `Layer.unwrap` and close over
|
|
2211
|
+
* them, and provide per-request services with MCP middleware.
|
|
2212
|
+
*
|
|
1783
2213
|
* @see {@link registerPrompt} for the Effect-level prompt registration API
|
|
2214
|
+
* @see {@link middleware} for providing request-level dependencies
|
|
1784
2215
|
*
|
|
1785
2216
|
* @stability unstable
|
|
1786
2217
|
* @category layers
|
|
1787
2218
|
* @since 4.0.0
|
|
1788
2219
|
*/
|
|
1789
|
-
export const prompt = options => Layer.effectDiscard(registerPrompt(options))
|
|
2220
|
+
export const prompt = options => Layer.effectDiscard(registerPrompt(options));
|
|
1790
2221
|
/**
|
|
1791
2222
|
* Collects structured input from the current MCP client and decodes the
|
|
1792
2223
|
* accepted response with `schema`.
|
|
@@ -1834,6 +2265,21 @@ export const elicit = /*#__PURE__*/Effect.fnUntraced(function* (options) {
|
|
|
1834
2265
|
* @since 4.0.0
|
|
1835
2266
|
*/
|
|
1836
2267
|
export const clientCapabilities = /*#__PURE__*/McpRequestContext.useSync(_ => _.clientCapabilities);
|
|
2268
|
+
/**
|
|
2269
|
+
* Decodes an `Mcp-Name` header, including base64-wrapped values.
|
|
2270
|
+
* Returns `undefined` for malformed values.
|
|
2271
|
+
*
|
|
2272
|
+
* **Details**
|
|
2273
|
+
*
|
|
2274
|
+
* Use in `HttpRouter.middleware` to identify the tool, prompt or resource
|
|
2275
|
+
* targeted by a `2026-07-28` request. Earlier protocols carry the name only
|
|
2276
|
+
* in the JSON-RPC body.
|
|
2277
|
+
*
|
|
2278
|
+
* @stability unstable
|
|
2279
|
+
* @category decoding
|
|
2280
|
+
* @since 4.0.0
|
|
2281
|
+
*/
|
|
2282
|
+
export const decodeNameHeader = value => McpProtocolInternal.decodeRoutingHeader(value);
|
|
1837
2283
|
// -----------------------------------------------------------------------------
|
|
1838
2284
|
// Internal
|
|
1839
2285
|
// -----------------------------------------------------------------------------
|