effect 4.0.3 → 4.0.5
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/AGENTS.md +24 -0
- package/CLAUDE.md +24 -0
- package/ai-docs/package.json +2 -2
- package/ai-docs/src/52_graphql/10_basics.ts +117 -0
- package/ai-docs/src/52_graphql/20_testing.ts +45 -0
- package/ai-docs/src/52_graphql/30_batching.ts +118 -0
- package/ai-docs/src/52_graphql/40_aliased-batching.ts +124 -0
- package/ai-docs/src/52_graphql/50_errors-and-retries.ts +74 -0
- package/ai-docs/src/52_graphql/index.md +6 -0
- package/dist/Array.d.ts +90 -6
- package/dist/Array.d.ts.map +1 -1
- package/dist/Array.js +4 -2
- package/dist/Array.js.map +1 -1
- package/dist/Channel.d.ts +6 -1
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +17 -3
- package/dist/Channel.js.map +1 -1
- package/dist/ConfigProvider.d.ts.map +1 -1
- package/dist/ConfigProvider.js +33 -32
- package/dist/ConfigProvider.js.map +1 -1
- package/dist/Context.d.ts.map +1 -1
- package/dist/Context.js +9 -0
- package/dist/Context.js.map +1 -1
- package/dist/Duration.d.ts.map +1 -1
- package/dist/Duration.js +2 -5
- package/dist/Duration.js.map +1 -1
- package/dist/Effect.d.ts +61 -19
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +58 -39
- package/dist/Effect.js.map +1 -1
- package/dist/FileSystem.d.ts +23 -9
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js.map +1 -1
- package/dist/Match.d.ts +20 -6
- package/dist/Match.d.ts.map +1 -1
- package/dist/Match.js +2 -2
- package/dist/Match.js.map +1 -1
- package/dist/Path.d.ts +37 -5
- package/dist/Path.d.ts.map +1 -1
- package/dist/Path.js +36 -5
- package/dist/Path.js.map +1 -1
- package/dist/RequestResolver.d.ts.map +1 -1
- package/dist/RequestResolver.js +4 -10
- package/dist/RequestResolver.js.map +1 -1
- package/dist/Scheduler.d.ts +9 -0
- package/dist/Scheduler.d.ts.map +1 -1
- package/dist/Scheduler.js +9 -0
- package/dist/Scheduler.js.map +1 -1
- package/dist/Schema.d.ts +15 -2
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +16 -2
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaGetter.d.ts +4 -0
- package/dist/SchemaGetter.d.ts.map +1 -1
- package/dist/SchemaGetter.js +52 -33
- package/dist/SchemaGetter.js.map +1 -1
- package/dist/Sink.d.ts.map +1 -1
- package/dist/Sink.js +38 -17
- package/dist/Sink.js.map +1 -1
- package/dist/Stream.d.ts +11 -0
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +16 -1
- package/dist/Stream.js.map +1 -1
- package/dist/String.d.ts +12 -0
- package/dist/String.d.ts.map +1 -1
- package/dist/String.js +17 -4
- package/dist/String.js.map +1 -1
- package/dist/TxRef.d.ts.map +1 -1
- package/dist/TxRef.js +3 -2
- package/dist/TxRef.js.map +1 -1
- package/dist/Utils.js +8 -3
- package/dist/Utils.js.map +1 -1
- package/dist/ai/AiError.d.ts +10 -10
- package/dist/ai/AiError.d.ts.map +1 -1
- package/dist/ai/AiError.js +1 -1
- package/dist/ai/AiError.js.map +1 -1
- package/dist/ai/AnthropicStructuredOutput.js +0 -2
- package/dist/ai/AnthropicStructuredOutput.js.map +1 -1
- package/dist/ai/Chat.d.ts +2 -2
- package/dist/ai/Chat.d.ts.map +1 -1
- package/dist/ai/Decision.d.ts +70 -19
- package/dist/ai/Decision.d.ts.map +1 -1
- package/dist/ai/Decision.js +37 -3
- package/dist/ai/Decision.js.map +1 -1
- package/dist/ai/DecisionModel.js +1 -1
- package/dist/ai/DecisionModel.js.map +1 -1
- package/dist/ai/LanguageModel.d.ts +38 -7
- package/dist/ai/LanguageModel.d.ts.map +1 -1
- package/dist/ai/LanguageModel.js +70 -40
- package/dist/ai/LanguageModel.js.map +1 -1
- package/dist/ai/McpServer.d.ts +61 -52
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +134 -50
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/Prompt.d.ts.map +1 -1
- package/dist/ai/Prompt.js +28 -5
- package/dist/ai/Prompt.js.map +1 -1
- package/dist/ai/Response.d.ts +5 -4
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js.map +1 -1
- package/dist/cli/Completions.d.ts +5 -0
- package/dist/cli/Completions.d.ts.map +1 -1
- package/dist/cli/Completions.js.map +1 -1
- package/dist/cli/Flag.d.ts +100 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +33 -0
- package/dist/cli/Flag.js.map +1 -1
- package/dist/cli/Param.d.ts +87 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +30 -0
- package/dist/cli/Param.js.map +1 -1
- package/dist/cli/internal/command.d.ts.map +1 -1
- package/dist/cli/internal/command.js +2 -1
- package/dist/cli/internal/command.js.map +1 -1
- package/dist/cli/internal/completions/bash.js +4 -3
- package/dist/cli/internal/completions/bash.js.map +1 -1
- package/dist/cli/internal/completions/descriptor.js +8 -1
- package/dist/cli/internal/completions/descriptor.js.map +1 -1
- package/dist/cli/internal/completions/fish.js +4 -4
- package/dist/cli/internal/completions/fish.js.map +1 -1
- package/dist/cli/internal/completions/powershell.js +3 -2
- package/dist/cli/internal/completions/powershell.js.map +1 -1
- package/dist/cli/internal/completions/zsh.js +7 -3
- package/dist/cli/internal/completions/zsh.js.map +1 -1
- package/dist/cli/internal/parser.js +11 -3
- package/dist/cli/internal/parser.js.map +1 -1
- package/dist/cli/internal/wizard.d.ts.map +1 -1
- package/dist/cli/internal/wizard.js +2 -1
- package/dist/cli/internal/wizard.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts +1 -0
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +113 -21
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +20 -12
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Runners.d.ts.map +1 -1
- package/dist/cluster/Runners.js +54 -34
- package/dist/cluster/Runners.js.map +1 -1
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +6 -4
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +1 -1
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/encoding/Sse.d.ts +6 -0
- package/dist/encoding/Sse.d.ts.map +1 -1
- package/dist/encoding/Sse.js +63 -71
- package/dist/encoding/Sse.js.map +1 -1
- package/dist/graphql/GraphQL.d.ts +349 -0
- package/dist/graphql/GraphQL.d.ts.map +1 -0
- package/dist/graphql/GraphQL.js +207 -0
- package/dist/graphql/GraphQL.js.map +1 -0
- package/dist/graphql/GraphQLClient.d.ts +562 -0
- package/dist/graphql/GraphQLClient.d.ts.map +1 -0
- package/dist/graphql/GraphQLClient.js +505 -0
- package/dist/graphql/GraphQLClient.js.map +1 -0
- package/dist/graphql/GraphQLClientError.d.ts +445 -0
- package/dist/graphql/GraphQLClientError.d.ts.map +1 -0
- package/dist/graphql/GraphQLClientError.js +479 -0
- package/dist/graphql/GraphQLClientError.js.map +1 -0
- package/dist/graphql/GraphQLGroup.d.ts +118 -0
- package/dist/graphql/GraphQLGroup.d.ts.map +1 -0
- package/dist/graphql/GraphQLGroup.js +109 -0
- package/dist/graphql/GraphQLGroup.js.map +1 -0
- package/dist/graphql/GraphQLMiddleware.d.ts +249 -0
- package/dist/graphql/GraphQLMiddleware.d.ts.map +1 -0
- package/dist/graphql/GraphQLMiddleware.js +130 -0
- package/dist/graphql/GraphQLMiddleware.js.map +1 -0
- package/dist/graphql/GraphQLProtocol.d.ts +969 -0
- package/dist/graphql/GraphQLProtocol.d.ts.map +1 -0
- package/dist/graphql/GraphQLProtocol.js +809 -0
- package/dist/graphql/GraphQLProtocol.js.map +1 -0
- package/dist/graphql/GraphQLResolver.d.ts +453 -0
- package/dist/graphql/GraphQLResolver.d.ts.map +1 -0
- package/dist/graphql/GraphQLResolver.js +582 -0
- package/dist/graphql/GraphQLResolver.js.map +1 -0
- package/dist/graphql/index.d.ts +40 -0
- package/dist/graphql/index.d.ts.map +1 -0
- package/dist/graphql/index.js +41 -0
- package/dist/graphql/index.js.map +1 -0
- package/dist/http/FetchHttpClient.d.ts +6 -3
- package/dist/http/FetchHttpClient.d.ts.map +1 -1
- package/dist/http/FetchHttpClient.js +6 -3
- package/dist/http/FetchHttpClient.js.map +1 -1
- package/dist/http/FindMyWay/internal/router.js +2 -1
- package/dist/http/FindMyWay/internal/router.js.map +1 -1
- package/dist/http/Headers.d.ts +3 -3
- package/dist/http/Headers.d.ts.map +1 -1
- package/dist/http/Headers.js +6 -5
- package/dist/http/Headers.js.map +1 -1
- package/dist/http/HttpClient.d.ts +27 -0
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +38 -11
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpClientError.d.ts.map +1 -1
- package/dist/http/HttpClientError.js +8 -6
- package/dist/http/HttpClientError.js.map +1 -1
- package/dist/http/HttpClientRequest.d.ts +147 -4
- package/dist/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/http/HttpClientRequest.js +47 -1
- package/dist/http/HttpClientRequest.js.map +1 -1
- package/dist/http/HttpEffect.d.ts.map +1 -1
- package/dist/http/HttpEffect.js +14 -7
- package/dist/http/HttpEffect.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts +60 -0
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +93 -32
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpRouter.d.ts +35 -0
- package/dist/http/HttpRouter.d.ts.map +1 -1
- package/dist/http/HttpRouter.js +87 -13
- package/dist/http/HttpRouter.js.map +1 -1
- package/dist/http/HttpServerError.d.ts.map +1 -1
- package/dist/http/HttpServerError.js +6 -4
- package/dist/http/HttpServerError.js.map +1 -1
- package/dist/http/HttpServerRequest.js +2 -2
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/HttpServerResponse.d.ts +8 -6
- package/dist/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/http/HttpServerResponse.js +27 -16
- package/dist/http/HttpServerResponse.js.map +1 -1
- package/dist/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/http/HttpStaticServer.js +4 -10
- package/dist/http/HttpStaticServer.js.map +1 -1
- package/dist/http/HttpTraceContext.js +1 -1
- package/dist/http/HttpTraceContext.js.map +1 -1
- package/dist/http/Multipart.d.ts.map +1 -1
- package/dist/http/Multipart.js +15 -1
- package/dist/http/Multipart.js.map +1 -1
- package/dist/http/Url.d.ts.map +1 -1
- package/dist/http/Url.js +2 -1
- package/dist/http/Url.js.map +1 -1
- package/dist/http/UrlParams.d.ts +112 -8
- package/dist/http/UrlParams.d.ts.map +1 -1
- package/dist/http/UrlParams.js +141 -14
- package/dist/http/UrlParams.js.map +1 -1
- package/dist/http/internal/compression.d.ts +1 -1
- package/dist/http/internal/compression.d.ts.map +1 -1
- package/dist/http/internal/compression.js +2 -10
- package/dist/http/internal/compression.js.map +1 -1
- package/dist/http/internal/compressionBody.d.ts +2 -0
- package/dist/http/internal/compressionBody.d.ts.map +1 -0
- package/dist/http/internal/compressionBody.js +36 -0
- package/dist/http/internal/compressionBody.js.map +1 -0
- package/dist/http/internal/decompression.d.ts +2 -0
- package/dist/http/internal/decompression.d.ts.map +1 -0
- package/dist/http/internal/decompression.js +162 -0
- package/dist/http/internal/decompression.js.map +1 -0
- package/dist/http/internal/tracing.js +14 -4
- package/dist/http/internal/tracing.js.map +1 -1
- package/dist/http/internal/urlParams.d.ts +2 -0
- package/dist/http/internal/urlParams.d.ts.map +1 -0
- package/dist/http/internal/urlParams.js +4 -0
- package/dist/http/internal/urlParams.js.map +1 -0
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +2 -1
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/http-api/HttpApiScalar.d.ts +5 -0
- package/dist/http-api/HttpApiScalar.d.ts.map +1 -1
- package/dist/http-api/HttpApiScalar.js.map +1 -1
- package/dist/internal/core.js +17 -1
- package/dist/internal/core.js.map +1 -1
- package/dist/internal/dateTime.js +40 -35
- package/dist/internal/dateTime.js.map +1 -1
- package/dist/internal/effect.js +13 -6
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/graphql.d.ts +2 -0
- package/dist/internal/graphql.d.ts.map +1 -0
- package/dist/internal/graphql.js +205 -0
- package/dist/internal/graphql.js.map +1 -0
- package/dist/internal/graphqlHeaders.d.ts +4 -0
- package/dist/internal/graphqlHeaders.d.ts.map +1 -0
- package/dist/internal/graphqlHeaders.js +11 -0
- package/dist/internal/graphqlHeaders.js.map +1 -0
- package/dist/internal/request.js +20 -1
- package/dist/internal/request.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +4 -1
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/schema/toJsonSchemaDocument.js +29 -5
- package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/net/Host.d.ts +49 -0
- package/dist/net/Host.d.ts.map +1 -1
- package/dist/net/Host.js +55 -0
- package/dist/net/Host.js.map +1 -1
- package/dist/net/NetAddress.d.ts +8 -0
- package/dist/net/NetAddress.d.ts.map +1 -1
- package/dist/net/NetAddress.js +8 -0
- package/dist/net/NetAddress.js.map +1 -1
- package/dist/observability/Otlp.d.ts +15 -0
- package/dist/observability/Otlp.d.ts.map +1 -1
- package/dist/observability/Otlp.js +3 -0
- package/dist/observability/Otlp.js.map +1 -1
- package/dist/observability/OtlpExporter.d.ts +8 -0
- package/dist/observability/OtlpExporter.d.ts.map +1 -1
- package/dist/observability/OtlpExporter.js +10 -1
- package/dist/observability/OtlpExporter.js.map +1 -1
- package/dist/observability/OtlpLogger.d.ts +17 -0
- package/dist/observability/OtlpLogger.d.ts.map +1 -1
- package/dist/observability/OtlpLogger.js +14 -1
- package/dist/observability/OtlpLogger.js.map +1 -1
- package/dist/observability/OtlpMetrics.d.ts +17 -0
- package/dist/observability/OtlpMetrics.d.ts.map +1 -1
- package/dist/observability/OtlpMetrics.js +13 -0
- package/dist/observability/OtlpMetrics.js.map +1 -1
- package/dist/observability/OtlpTracer.d.ts +17 -0
- package/dist/observability/OtlpTracer.d.ts.map +1 -1
- package/dist/observability/OtlpTracer.js +15 -2
- package/dist/observability/OtlpTracer.js.map +1 -1
- package/dist/reactivity/AsyncResult.d.ts +6 -0
- package/dist/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/reactivity/AsyncResult.js +27 -0
- package/dist/reactivity/AsyncResult.js.map +1 -1
- package/dist/reactivity/AtomRegistry.js +3 -1
- package/dist/reactivity/AtomRegistry.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +6 -1
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +36 -9
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/socket/Socket.d.ts +6 -0
- package/dist/socket/Socket.d.ts.map +1 -1
- package/dist/socket/Socket.js.map +1 -1
- package/dist/sql/SqlClient.d.ts +8 -7
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +8 -7
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/testing/TestClock.d.ts +16 -3
- package/dist/testing/TestClock.d.ts.map +1 -1
- package/dist/testing/TestClock.js +112 -22
- package/dist/testing/TestClock.js.map +1 -1
- package/dist/workflow/Activity.js +1 -0
- package/dist/workflow/Activity.js.map +1 -1
- package/dist/workflow/DurableDeferred.d.ts.map +1 -1
- package/dist/workflow/DurableDeferred.js +32 -3
- package/dist/workflow/DurableDeferred.js.map +1 -1
- package/dist/workflow/Workflow.d.ts +22 -0
- package/dist/workflow/Workflow.d.ts.map +1 -1
- package/dist/workflow/Workflow.js +15 -3
- package/dist/workflow/Workflow.js.map +1 -1
- package/dist/workflow/WorkflowEngine.d.ts +44 -3
- package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
- package/dist/workflow/WorkflowEngine.js +45 -22
- package/dist/workflow/WorkflowEngine.js.map +1 -1
- package/package.json +6 -3
- package/src/Array.ts +95 -6
- package/src/Channel.ts +24 -3
- package/src/ConfigProvider.ts +40 -44
- package/src/Context.ts +9 -0
- package/src/Duration.ts +4 -5
- package/src/Effect.ts +140 -53
- package/src/FileSystem.ts +23 -9
- package/src/Match.ts +65 -12
- package/src/Path.ts +52 -7
- package/src/RequestResolver.ts +4 -10
- package/src/Scheduler.ts +9 -0
- package/src/Schema.ts +25 -4
- package/src/SchemaGetter.ts +47 -35
- package/src/Sink.ts +45 -18
- package/src/Stream.ts +33 -4
- package/src/String.ts +17 -4
- package/src/TxRef.ts +4 -2
- package/src/Utils.ts +8 -5
- package/src/ai/AiError.ts +3 -1
- package/src/ai/AnthropicStructuredOutput.ts +2 -2
- package/src/ai/Chat.ts +2 -2
- package/src/ai/Decision.ts +70 -21
- package/src/ai/DecisionModel.ts +1 -1
- package/src/ai/LanguageModel.ts +141 -63
- package/src/ai/McpServer.ts +259 -145
- package/src/ai/Prompt.ts +24 -10
- package/src/ai/Response.ts +6 -3
- package/src/cli/Completions.ts +5 -0
- package/src/cli/Flag.ts +101 -0
- package/src/cli/Param.ts +96 -0
- package/src/cli/internal/command.ts +2 -1
- package/src/cli/internal/completions/bash.ts +4 -3
- package/src/cli/internal/completions/descriptor.ts +10 -1
- package/src/cli/internal/completions/fish.ts +4 -4
- package/src/cli/internal/completions/powershell.ts +5 -2
- package/src/cli/internal/completions/zsh.ts +7 -3
- package/src/cli/internal/parser.ts +12 -3
- package/src/cli/internal/wizard.ts +2 -1
- package/src/cluster/ClusterWorkflowEngine.ts +143 -36
- package/src/cluster/MessageStorage.ts +14 -3
- package/src/cluster/Runners.ts +88 -66
- package/src/cluster/Sharding.ts +12 -9
- package/src/cluster/internal/entityManager.ts +1 -1
- package/src/encoding/Sse.ts +70 -80
- package/src/graphql/GraphQL.ts +494 -0
- package/src/graphql/GraphQLClient.ts +924 -0
- package/src/graphql/GraphQLClientError.ts +542 -0
- package/src/graphql/GraphQLGroup.ts +167 -0
- package/src/graphql/GraphQLMiddleware.ts +253 -0
- package/src/graphql/GraphQLProtocol.ts +1540 -0
- package/src/graphql/GraphQLResolver.ts +1038 -0
- package/src/graphql/index.ts +48 -0
- package/src/http/FetchHttpClient.ts +6 -3
- package/src/http/FindMyWay/internal/router.ts +2 -1
- package/src/http/Headers.ts +6 -9
- package/src/http/HttpClient.ts +72 -11
- package/src/http/HttpClientError.ts +10 -6
- package/src/http/HttpClientRequest.ts +173 -7
- package/src/http/HttpEffect.ts +11 -5
- package/src/http/HttpMiddleware.ts +113 -34
- package/src/http/HttpRouter.ts +95 -13
- package/src/http/HttpServerError.ts +8 -4
- package/src/http/HttpServerRequest.ts +2 -2
- package/src/http/HttpServerResponse.ts +28 -16
- package/src/http/HttpStaticServer.ts +4 -10
- package/src/http/HttpTraceContext.ts +1 -1
- package/src/http/Multipart.ts +17 -1
- package/src/http/Url.ts +2 -1
- package/src/http/UrlParams.ts +225 -26
- package/src/http/internal/compression.ts +3 -17
- package/src/http/internal/compressionBody.ts +56 -0
- package/src/http/internal/decompression.ts +226 -0
- package/src/http/internal/tracing.ts +21 -4
- package/src/http/internal/urlParams.ts +5 -0
- package/src/http-api/HttpApiClient.ts +2 -1
- package/src/http-api/HttpApiScalar.ts +5 -0
- package/src/internal/core.ts +21 -1
- package/src/internal/dateTime.ts +13 -10
- package/src/internal/effect.ts +13 -7
- package/src/internal/graphql.ts +286 -0
- package/src/internal/graphqlHeaders.ts +11 -0
- package/src/internal/request.ts +31 -3
- package/src/internal/schema/toCodeDocument.ts +7 -1
- package/src/internal/schema/toJsonSchemaDocument.ts +34 -2
- package/src/internal/version.ts +1 -1
- package/src/net/Host.ts +72 -0
- package/src/net/NetAddress.ts +9 -0
- package/src/observability/Otlp.ts +18 -0
- package/src/observability/OtlpExporter.ts +14 -3
- package/src/observability/OtlpLogger.ts +31 -2
- package/src/observability/OtlpMetrics.ts +30 -1
- package/src/observability/OtlpTracer.ts +32 -3
- package/src/reactivity/AsyncResult.ts +31 -0
- package/src/reactivity/AtomRegistry.ts +3 -1
- package/src/rpc/RpcClient.ts +6 -1
- package/src/rpc/RpcServer.ts +55 -15
- package/src/socket/Socket.ts +6 -0
- package/src/sql/SqlClient.ts +9 -7
- package/src/testing/TestClock.ts +144 -29
- package/src/workflow/Activity.ts +1 -0
- package/src/workflow/DurableDeferred.ts +43 -5
- package/src/workflow/Workflow.ts +31 -5
- package/src/workflow/WorkflowEngine.ts +107 -25
package/src/ai/McpServer.ts
CHANGED
|
@@ -104,8 +104,19 @@ interface QueuedServerNotification {
|
|
|
104
104
|
const internalState = new WeakMap<object, {
|
|
105
105
|
readonly core: McpCore.McpCore
|
|
106
106
|
readonly notifications: Queue.Dequeue<QueuedServerNotification>
|
|
107
|
-
readonly notificationDelivery: { consumers: number; listChangeRevision: number }
|
|
107
|
+
readonly notificationDelivery: { consumers: number; listChangeRevision: number; requestEndpoints: number }
|
|
108
108
|
}>()
|
|
109
|
+
|
|
110
|
+
// Request-scoped HTTP servers deliver a request's own notifications through
|
|
111
|
+
// that request's server instead of the shared notification queue.
|
|
112
|
+
const RequestNotificationQueue = Context.Reference<Queue.Queue<QueuedServerNotification> | undefined>(
|
|
113
|
+
"effect/ai/McpServer/RequestNotificationQueue",
|
|
114
|
+
{ defaultValue: () => undefined }
|
|
115
|
+
)
|
|
116
|
+
// Progress and logs belong to the request that emitted them.
|
|
117
|
+
const isRequestNotification = (notification: McpCore.ServerNotification) =>
|
|
118
|
+
notification._tag === "Progress" || notification._tag === "LoggingMessage"
|
|
119
|
+
|
|
109
120
|
type ServerExtensions = NonNullable<ServerCapabilities["extensions"]>
|
|
110
121
|
type ServerNotificationRequest<
|
|
111
122
|
R extends Rpc.Any = RpcGroup.Rpcs<typeof BroadcastServerNotificationRpcs>
|
|
@@ -322,7 +333,10 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
322
333
|
readonly annotations: Context.Context<never>
|
|
323
334
|
}> = []
|
|
324
335
|
const notificationsQueue = yield* Queue.make<QueuedServerNotification>()
|
|
325
|
-
const notificationDelivery = { consumers: 0, listChangeRevision: 0 }
|
|
336
|
+
const notificationDelivery = { consumers: 0, listChangeRevision: 0, requestEndpoints: 0 }
|
|
337
|
+
// With only request-scoped endpoints, no long-lived server ever takes from the shared queue.
|
|
338
|
+
const withoutSharedConsumer = () =>
|
|
339
|
+
notificationDelivery.consumers === 0 && notificationDelivery.requestEndpoints > 0
|
|
326
340
|
const pendingListChanges = new Map<string, QueuedServerNotification>()
|
|
327
341
|
const dispatcher = (yield* Scheduler).makeDispatcher()
|
|
328
342
|
const notifications = yield* RpcClient.makeNoSerialization(BroadcastServerNotificationRpcs, {
|
|
@@ -344,6 +358,26 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
344
358
|
requestContext: Context.getOrUndefined(fiber.context, McpRequestContext),
|
|
345
359
|
requestHeaders: Context.getOrUndefined(fiber.context, HttpServerRequest.HttpServerRequest)?.headers
|
|
346
360
|
}
|
|
361
|
+
// write resumes the caller synchronously, so defer it until delivery completes.
|
|
362
|
+
const acknowledge = Effect.suspend(() =>
|
|
363
|
+
notifications.write({
|
|
364
|
+
clientId: 0,
|
|
365
|
+
requestId: message.id,
|
|
366
|
+
_tag: "Exit",
|
|
367
|
+
exit: Exit.void
|
|
368
|
+
})
|
|
369
|
+
)
|
|
370
|
+
// A request-scoped endpoint delivers its request's own progress and logs on that request's response.
|
|
371
|
+
const requestQueue = Context.get(fiber.context, RequestNotificationQueue)
|
|
372
|
+
if (
|
|
373
|
+
requestQueue !== undefined && queued.requestContext !== undefined && isRequestNotification(notification)
|
|
374
|
+
) {
|
|
375
|
+
Queue.offerUnsafe(requestQueue, queued)
|
|
376
|
+
return Effect.andThen(Deferred.await(delivered), acknowledge)
|
|
377
|
+
}
|
|
378
|
+
if (withoutSharedConsumer()) {
|
|
379
|
+
return acknowledge
|
|
380
|
+
}
|
|
347
381
|
let enqueued = false
|
|
348
382
|
if (message.tag.includes("list_changed")) {
|
|
349
383
|
const revision = ++notificationDelivery.listChangeRevision
|
|
@@ -364,15 +398,6 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
364
398
|
enqueued = true
|
|
365
399
|
Queue.offerUnsafe(notificationsQueue, queued)
|
|
366
400
|
}
|
|
367
|
-
// write resumes the caller synchronously, so defer it until delivery completes.
|
|
368
|
-
const acknowledge = Effect.suspend(() =>
|
|
369
|
-
notifications.write({
|
|
370
|
-
clientId: 0,
|
|
371
|
-
requestId: message.id,
|
|
372
|
-
_tag: "Exit",
|
|
373
|
-
exit: Exit.void
|
|
374
|
-
})
|
|
375
|
-
)
|
|
376
401
|
return enqueued && queued.requestContext !== undefined && notificationDelivery.consumers > 0
|
|
377
402
|
? Effect.andThen(Deferred.await(delivered), acknowledge)
|
|
378
403
|
: acknowledge
|
|
@@ -383,7 +408,7 @@ export class McpServer extends Context.Service<McpServer, {
|
|
|
383
408
|
const service = McpServer.of({
|
|
384
409
|
notifications: notifications.client,
|
|
385
410
|
notifyElicitationComplete: ({ clientId, elicitationId }) =>
|
|
386
|
-
Deferred.make<void>().pipe(
|
|
411
|
+
withoutSharedConsumer() ? Effect.void : Deferred.make<void>().pipe(
|
|
387
412
|
Effect.flatMap((delivered) =>
|
|
388
413
|
Queue.offer(notificationsQueue, {
|
|
389
414
|
notification: McpCore.ServerNotification.ElicitationComplete({ elicitationId }),
|
|
@@ -727,7 +752,11 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
727
752
|
readonly allowSubscriptions?: boolean | undefined
|
|
728
753
|
},
|
|
729
754
|
runtime: McpRuntime.ServerRuntimeShape,
|
|
730
|
-
transport: "custom" | "http" | "stdio"
|
|
755
|
+
transport: "custom" | "http" | "stdio",
|
|
756
|
+
requestScoped?: {
|
|
757
|
+
readonly notifications: Queue.Dequeue<QueuedServerNotification>
|
|
758
|
+
readonly handlers: Context.Context<never>
|
|
759
|
+
}
|
|
731
760
|
) {
|
|
732
761
|
const protocol = yield* RpcServer.Protocol
|
|
733
762
|
const server = yield* McpServer
|
|
@@ -817,7 +846,7 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
817
846
|
})
|
|
818
847
|
let writeFromClient!: (clientId: number, message: RpcMessage.FromClientEncoded) => Effect.Effect<void>
|
|
819
848
|
const { core, notificationDelivery, notifications } = internalState.get(server)!
|
|
820
|
-
const handlers = yield* runtime.installHandlers({
|
|
849
|
+
const handlers = requestScoped?.handlers ?? (yield* runtime.installHandlers({
|
|
821
850
|
core,
|
|
822
851
|
subscribeServerNotifications: PubSub.subscribe(serverNotifications),
|
|
823
852
|
getListChangeRevision: () => notificationDelivery.listChangeRevision,
|
|
@@ -831,7 +860,7 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
831
860
|
}),
|
|
832
861
|
defaultLogLevel,
|
|
833
862
|
serverInfo: options
|
|
834
|
-
})
|
|
863
|
+
}))
|
|
835
864
|
|
|
836
865
|
const clients = yield* RcMap.make({
|
|
837
866
|
lookup: Effect.fnUntraced(function*(key: McpClientKey) {
|
|
@@ -1252,17 +1281,19 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
1252
1281
|
})
|
|
1253
1282
|
}
|
|
1254
1283
|
|
|
1255
|
-
|
|
1256
|
-
Effect.
|
|
1257
|
-
notificationDelivery.consumers++
|
|
1258
|
-
}),
|
|
1259
|
-
() =>
|
|
1284
|
+
if (requestScoped === undefined) {
|
|
1285
|
+
yield* Effect.acquireRelease(
|
|
1260
1286
|
Effect.sync(() => {
|
|
1261
|
-
notificationDelivery.consumers
|
|
1262
|
-
})
|
|
1263
|
-
|
|
1287
|
+
notificationDelivery.consumers++
|
|
1288
|
+
}),
|
|
1289
|
+
() =>
|
|
1290
|
+
Effect.sync(() => {
|
|
1291
|
+
notificationDelivery.consumers--
|
|
1292
|
+
})
|
|
1293
|
+
)
|
|
1294
|
+
}
|
|
1264
1295
|
const notificationTails = new Map<number, Deferred.Deferred<void>>()
|
|
1265
|
-
yield* Queue.take(notifications).pipe(
|
|
1296
|
+
yield* Queue.take(requestScoped?.notifications ?? notifications).pipe(
|
|
1266
1297
|
Effect.flatMap(Effect.fnUntraced(function*(queued) {
|
|
1267
1298
|
const { delivered, listChangeRevision, notification, targetClientId, requestContext, requestHeaders } = queued
|
|
1268
1299
|
if (McpProtocolInternal.isSubscriptionServerNotification(notification)) {
|
|
@@ -1276,7 +1307,7 @@ const runWithRuntime = Effect.fnUntraced(function*(
|
|
|
1276
1307
|
runtime.disconnect(clientId)
|
|
1277
1308
|
}
|
|
1278
1309
|
}
|
|
1279
|
-
const requestNotification = notification
|
|
1310
|
+
const requestNotification = isRequestNotification(notification)
|
|
1280
1311
|
const deliveryClientIds = requestNotification && requestContext !== undefined
|
|
1281
1312
|
? [requestContext.clientId]
|
|
1282
1313
|
: targetClientId === undefined
|
|
@@ -1594,11 +1625,20 @@ const mcpStdioSerialization = (
|
|
|
1594
1625
|
* Method not found. Request-scoped progress and logs, legacy protocols, and
|
|
1595
1626
|
* default subscription behavior are unchanged.
|
|
1596
1627
|
*
|
|
1628
|
+
* The layer runs one long-lived MCP server that every POST shares. For
|
|
1629
|
+
* serverless hosts where execution must belong to each request, use
|
|
1630
|
+
* `layerHttpRequestScoped` instead.
|
|
1631
|
+
*
|
|
1597
1632
|
* `layerHttp` always implements the single-endpoint Streamable HTTP topology.
|
|
1598
1633
|
* Using `v2024_11_05` here is a custom compatibility transport for that
|
|
1599
1634
|
* revision's schema. It does not implement the historical two-endpoint
|
|
1600
1635
|
* HTTP+SSE transport, GET SSE, event resumption, or session expiry.
|
|
1601
1636
|
*
|
|
1637
|
+
* **Gotchas**
|
|
1638
|
+
*
|
|
1639
|
+
* This layer starts a scoped server fiber. For sharing it across Cloudflare
|
|
1640
|
+
* Workers requests, see `HttpRouter.toWebHandler` for setup and limitations.
|
|
1641
|
+
*
|
|
1602
1642
|
* @see {@link layerStdio} for exposing the server over stdio
|
|
1603
1643
|
* @see {@link layer} for the base MCP server layer without a transport protocol
|
|
1604
1644
|
*
|
|
@@ -1628,6 +1668,105 @@ export const layerHttp = (options: {
|
|
|
1628
1668
|
)
|
|
1629
1669
|
}
|
|
1630
1670
|
|
|
1671
|
+
/**
|
|
1672
|
+
* Registers a request-scoped Streamable HTTP MCP endpoint at `options.path`.
|
|
1673
|
+
*
|
|
1674
|
+
* **When to use**
|
|
1675
|
+
*
|
|
1676
|
+
* Use when serving on serverless hosts such as Cloudflare Workers, where execution must
|
|
1677
|
+
* belong to the HTTP request rather than a shared long-lived server.
|
|
1678
|
+
*
|
|
1679
|
+
* **Details**
|
|
1680
|
+
*
|
|
1681
|
+
* Each POST runs its own server in the request scope, with no background
|
|
1682
|
+
* fiber, timer, or queue consumer left after the response body completes.
|
|
1683
|
+
* Only sessionless protocols such as `v2026_07_28` are accepted. Tools,
|
|
1684
|
+
* resources, prompts, completions, multi round-trip input requests, and the
|
|
1685
|
+
* request's own progress and log notifications are supported. Legacy reverse
|
|
1686
|
+
* requests through `McpServer.elicit` are not available.
|
|
1687
|
+
*
|
|
1688
|
+
* Discovery advertises `listChanged: false`, `subscriptions/listen` returns
|
|
1689
|
+
* Method not found, and DELETE returns `405`. Request-scoped clients receive
|
|
1690
|
+
* no broadcast notifications such as list changes. Those still reach clients
|
|
1691
|
+
* of a `layerHttp` endpoint sharing the same `McpServer`, and are dropped when
|
|
1692
|
+
* no such endpoint exists. Use `layerHttp` on a long-lived host for sessions,
|
|
1693
|
+
* subscriptions, or legacy reverse requests.
|
|
1694
|
+
*
|
|
1695
|
+
* HTTP admission, origin checks, and JSON-RPC errors follow `layerHttp`.
|
|
1696
|
+
* Configuring a sessionful protocol through an untyped caller fails layer
|
|
1697
|
+
* construction with `IllegalArgumentError`.
|
|
1698
|
+
*
|
|
1699
|
+
* @see {@link layerHttp} for the long-lived HTTP transport and HTTP admission policy
|
|
1700
|
+
*
|
|
1701
|
+
* @stability unstable
|
|
1702
|
+
* @category layers
|
|
1703
|
+
* @since 4.0.0
|
|
1704
|
+
*/
|
|
1705
|
+
export const layerHttpRequestScoped = (options: {
|
|
1706
|
+
readonly name: string
|
|
1707
|
+
readonly version: string
|
|
1708
|
+
readonly instructions?: string | undefined
|
|
1709
|
+
readonly description?: string | undefined
|
|
1710
|
+
readonly websiteUrl?: string | undefined
|
|
1711
|
+
readonly icons?: ReadonlyArray<McpSchema.Icon> | undefined
|
|
1712
|
+
readonly path: HttpRouter.PathInput
|
|
1713
|
+
readonly protocols: Arr.NonEmptyReadonlyArray<
|
|
1714
|
+
McpProtocol.ProtocolAdapter<McpProtocol.ProtocolVersion, McpProtocol.StatelessRuntimeDescriptor>
|
|
1715
|
+
>
|
|
1716
|
+
readonly extensions?: ServerExtensions | undefined
|
|
1717
|
+
readonly allowedOrigins?: ReadonlyArray<string> | undefined
|
|
1718
|
+
}): Layer.Layer<McpServer | McpServerClient, Cause.IllegalArgumentError, HttpRouter.HttpRouter> =>
|
|
1719
|
+
Layer.effectDiscard(Effect.gen(function*() {
|
|
1720
|
+
const runtime = yield* McpRuntime.ServerRuntime
|
|
1721
|
+
const stateful = runtime.protocols.find((protocol) => protocol.runtime._tag === "Stateful")
|
|
1722
|
+
if (stateful !== undefined) {
|
|
1723
|
+
return yield* new Cause.IllegalArgumentError(
|
|
1724
|
+
`McpServer.layerHttpRequestScoped does not support the sessionful MCP protocol ${stateful.protocolVersion}`
|
|
1725
|
+
)
|
|
1726
|
+
}
|
|
1727
|
+
const server = yield* McpServer
|
|
1728
|
+
const { core, notificationDelivery } = internalState.get(server)!
|
|
1729
|
+
// Subscriptions are disabled, so handlers hold no per-request state and
|
|
1730
|
+
// read registrations from the shared core on every call. Request services
|
|
1731
|
+
// still take precedence over the layer context captured here.
|
|
1732
|
+
const handlers = yield* (runtime.installHandlers({
|
|
1733
|
+
core,
|
|
1734
|
+
subscribeServerNotifications: Effect.die("Subscriptions are disabled for request-scoped MCP servers"),
|
|
1735
|
+
getListChangeRevision: () => notificationDelivery.listChangeRevision,
|
|
1736
|
+
defaultLogLevel: yield* CurrentLogLevel,
|
|
1737
|
+
serverInfo: options
|
|
1738
|
+
}) as Effect.Effect<Context.Context<never>>)
|
|
1739
|
+
yield* Effect.acquireRelease(
|
|
1740
|
+
Effect.sync(() => {
|
|
1741
|
+
notificationDelivery.requestEndpoints++
|
|
1742
|
+
}),
|
|
1743
|
+
() =>
|
|
1744
|
+
Effect.sync(() => {
|
|
1745
|
+
notificationDelivery.requestEndpoints--
|
|
1746
|
+
})
|
|
1747
|
+
)
|
|
1748
|
+
// Each POST runs its own RPC server in the request scope, so no fiber,
|
|
1749
|
+
// timer, or queue consumer outlives the request that created it.
|
|
1750
|
+
yield* addMcpHttpRoutes(
|
|
1751
|
+
options,
|
|
1752
|
+
Effect.gen(function*() {
|
|
1753
|
+
const { httpEffect, protocol } = yield* RpcServer.makeProtocolWithHttpEffect().pipe(
|
|
1754
|
+
Effect.provideService(RpcSerialization.RpcSerialization, mcpHttpSerialization)
|
|
1755
|
+
)
|
|
1756
|
+
const notifications = yield* Queue.make<QueuedServerNotification>()
|
|
1757
|
+
yield* runWithRuntime(options, runtime, "http", { notifications, handlers }).pipe(
|
|
1758
|
+
Effect.provideService(RpcServer.Protocol, protocol),
|
|
1759
|
+
Effect.provideService(McpServer, server),
|
|
1760
|
+
Effect.forkScoped({ startImmediately: true })
|
|
1761
|
+
)
|
|
1762
|
+
return yield* Effect.provideService(httpEffect, RequestNotificationQueue, notifications)
|
|
1763
|
+
})
|
|
1764
|
+
)
|
|
1765
|
+
})).pipe(
|
|
1766
|
+
Layer.provideMerge(McpServer.layer),
|
|
1767
|
+
Layer.provide(McpRuntime.layer(options.protocols))
|
|
1768
|
+
)
|
|
1769
|
+
|
|
1631
1770
|
const layerMcpProtocolHttp = (options: {
|
|
1632
1771
|
readonly path: HttpRouter.PathInput
|
|
1633
1772
|
readonly allowedOrigins?: ReadonlyArray<string> | undefined
|
|
@@ -1638,81 +1777,96 @@ const layerMcpProtocolHttp = (options: {
|
|
|
1638
1777
|
McpRuntime.ServerRuntime | HttpRouter.HttpRouter
|
|
1639
1778
|
> =>
|
|
1640
1779
|
Layer.effect(RpcServer.Protocol)(Effect.gen(function*() {
|
|
1641
|
-
const runtime = yield* McpRuntime.ServerRuntime
|
|
1642
1780
|
const { httpEffect, protocol } = yield* RpcServer.makeProtocolWithHttpEffect().pipe(
|
|
1643
1781
|
Effect.provideService(RpcSerialization.RpcSerialization, mcpHttpSerialization)
|
|
1644
1782
|
)
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1783
|
+
yield* addMcpHttpRoutes(options, httpEffect)
|
|
1784
|
+
return protocol
|
|
1785
|
+
}))
|
|
1786
|
+
|
|
1787
|
+
const addMcpHttpRoutes = Effect.fnUntraced(function*(
|
|
1788
|
+
options: {
|
|
1789
|
+
readonly path: HttpRouter.PathInput
|
|
1790
|
+
readonly allowedOrigins?: ReadonlyArray<string> | undefined
|
|
1791
|
+
readonly allowSessionTermination?: boolean | undefined
|
|
1792
|
+
},
|
|
1793
|
+
httpEffect: Effect.Effect<
|
|
1794
|
+
HttpServerResponse.HttpServerResponse,
|
|
1795
|
+
never,
|
|
1796
|
+
Scope.Scope | HttpServerRequest.HttpServerRequest
|
|
1797
|
+
>
|
|
1798
|
+
) {
|
|
1799
|
+
const runtime = yield* McpRuntime.ServerRuntime
|
|
1800
|
+
const router = yield* HttpRouter.HttpRouter
|
|
1801
|
+
const allowSessionTermination = options.allowSessionTermination === true &&
|
|
1802
|
+
runtime.protocols.some((protocol) => protocol.runtime._tag === "Stateful")
|
|
1803
|
+
const forbidden = Effect.succeed(HttpServerResponse.empty({ status: 403 }))
|
|
1804
|
+
const withAllowedOrigin = (
|
|
1805
|
+
handler: (request: HttpServerRequest.HttpServerRequest) => Effect.Effect<HttpServerResponse.HttpServerResponse>
|
|
1806
|
+
) =>
|
|
1807
|
+
(request: HttpServerRequest.HttpServerRequest) =>
|
|
1808
|
+
isAllowedMcpOrigin(request, options.allowedOrigins) ? handler(request) : forbidden
|
|
1809
|
+
const methodNotAllowedResponse = Effect.succeed(HttpServerResponse.empty({
|
|
1810
|
+
status: 405,
|
|
1811
|
+
headers: { allow: allowSessionTermination ? "POST, DELETE" : "POST" }
|
|
1812
|
+
}))
|
|
1813
|
+
const methodNotAllowed = withAllowedOrigin(() => methodNotAllowedResponse)
|
|
1814
|
+
for (const method of ["GET", "PUT", "PATCH", "OPTIONS"] as const) {
|
|
1815
|
+
yield* router.add(method, options.path, methodNotAllowed)
|
|
1816
|
+
}
|
|
1817
|
+
yield* router.add(
|
|
1818
|
+
"DELETE",
|
|
1819
|
+
options.path,
|
|
1820
|
+
allowSessionTermination
|
|
1821
|
+
? withAllowedOrigin((request) => runtime.terminateHttpSession(request.headers))
|
|
1822
|
+
: methodNotAllowed
|
|
1823
|
+
)
|
|
1824
|
+
yield* router.add("POST", options.path, (request) => {
|
|
1825
|
+
if (!isAllowedMcpOrigin(request, options.allowedOrigins)) {
|
|
1826
|
+
return Effect.succeed(HttpServerResponse.empty({ status: 403 }))
|
|
1661
1827
|
}
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1828
|
+
if (mcpMediaTypes(request.headers["content-type"])[0] !== "application/json") {
|
|
1829
|
+
return Effect.succeed(HttpServerResponse.empty({ status: 415 }))
|
|
1830
|
+
}
|
|
1831
|
+
const accepted = mcpMediaTypes(request.headers["accept"])
|
|
1832
|
+
if (!accepted.includes("application/json") || !accepted.includes("text/event-stream")) {
|
|
1833
|
+
return Effect.succeed(HttpServerResponse.empty({ status: 406 }))
|
|
1834
|
+
}
|
|
1835
|
+
return Effect.gen(function*() {
|
|
1836
|
+
const parsed = yield* Effect.result(
|
|
1837
|
+
Effect.flatMap(request.text, Schema.decodeEffect(Schema.UnknownFromJsonString))
|
|
1838
|
+
)
|
|
1839
|
+
const admission = runtime.admitHttp(request.headers, parsed)
|
|
1840
|
+
if (admission._tag === "Rejected") {
|
|
1841
|
+
return admission.response
|
|
1675
1842
|
}
|
|
1676
|
-
const
|
|
1677
|
-
|
|
1678
|
-
|
|
1843
|
+
const toResponse = (response: HttpServerResponse.HttpServerResponse) => {
|
|
1844
|
+
// Completed responses may already contain notifications followed by the result.
|
|
1845
|
+
const hasMultipleMessages = response.body._tag === "Uint8Array" &&
|
|
1846
|
+
response.body.body.subarray(0, -1).includes(10)
|
|
1847
|
+
return admission.isSubscription || response.body._tag === "Stream" || hasMultipleMessages
|
|
1848
|
+
? toServerSentEvents(response, admission.isSubscription)
|
|
1849
|
+
: response
|
|
1679
1850
|
}
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
Effect.
|
|
1851
|
+
if (admission.acknowledge) {
|
|
1852
|
+
return yield* Effect.catchCause(
|
|
1853
|
+
Effect.map(httpEffect, toResponse),
|
|
1854
|
+
() => Effect.succeed(HttpServerResponse.empty({ status: 202 }))
|
|
1683
1855
|
)
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
const toResponse = (response: HttpServerResponse.HttpServerResponse) => {
|
|
1689
|
-
// Completed responses may already contain notifications followed by the result.
|
|
1690
|
-
const hasMultipleMessages = response.body._tag === "Uint8Array" &&
|
|
1691
|
-
response.body.body.subarray(0, -1).includes(10)
|
|
1692
|
-
return admission.isSubscription || response.body._tag === "Stream" || hasMultipleMessages
|
|
1693
|
-
? toServerSentEvents(response, admission.isSubscription)
|
|
1694
|
-
: response
|
|
1695
|
-
}
|
|
1696
|
-
if (admission.acknowledge) {
|
|
1697
|
-
return yield* Effect.catchCause(
|
|
1698
|
-
Effect.map(httpEffect, toResponse),
|
|
1699
|
-
() => Effect.succeed(HttpServerResponse.empty({ status: 202 }))
|
|
1700
|
-
)
|
|
1856
|
+
}
|
|
1857
|
+
return yield* Effect.flatMap(httpEffect, (response) => {
|
|
1858
|
+
if (response.body._tag !== "Uint8Array" || response.body.body.length > 0) {
|
|
1859
|
+
return Effect.succeed(toResponse(response))
|
|
1701
1860
|
}
|
|
1702
|
-
return
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
}
|
|
1706
|
-
|
|
1707
|
-
// https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#sending-messages-to-the-server
|
|
1708
|
-
return httpPostResponses.get(request)?.expected === 0
|
|
1709
|
-
? Effect.succeed(HttpServerResponse.stream(Stream.empty, { contentType: "text/event-stream" }))
|
|
1710
|
-
: Effect.die(new Error("MCP request ended without writing its response"))
|
|
1711
|
-
})
|
|
1861
|
+
// Only fully cancelled request POSTs may return an empty SSE response.
|
|
1862
|
+
// https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#sending-messages-to-the-server
|
|
1863
|
+
return httpPostResponses.get(request)?.expected === 0
|
|
1864
|
+
? Effect.succeed(HttpServerResponse.stream(Stream.empty, { contentType: "text/event-stream" }))
|
|
1865
|
+
: Effect.die(new Error("MCP request ended without writing its response"))
|
|
1712
1866
|
})
|
|
1713
1867
|
})
|
|
1714
|
-
|
|
1715
|
-
|
|
1868
|
+
})
|
|
1869
|
+
})
|
|
1716
1870
|
|
|
1717
1871
|
const mcpHttpSerialization: RpcSerialization.RpcSerialization["Service"] = (() => {
|
|
1718
1872
|
const serialization = mcpJsonRpcSerialization()
|
|
@@ -2123,12 +2277,6 @@ export type ResourceCompletions<Schemas extends ReadonlyArray<Schema.Constraint>
|
|
|
2123
2277
|
/**
|
|
2124
2278
|
* Registers an MCP resource or resource template from an Effect program.
|
|
2125
2279
|
*
|
|
2126
|
-
* **When to use**
|
|
2127
|
-
*
|
|
2128
|
-
* Use when you are already inside an Effect program with an `McpServer`
|
|
2129
|
-
* service and need to add a concrete resource or URI-template resource
|
|
2130
|
-
* directly.
|
|
2131
|
-
*
|
|
2132
2280
|
* @see {@link resource} for the layer-based resource registration wrapper
|
|
2133
2281
|
*
|
|
2134
2282
|
* @stability unstable
|
|
@@ -2139,12 +2287,6 @@ export const registerResource: {
|
|
|
2139
2287
|
/**
|
|
2140
2288
|
* Registers an MCP resource or resource template from an Effect program.
|
|
2141
2289
|
*
|
|
2142
|
-
* **When to use**
|
|
2143
|
-
*
|
|
2144
|
-
* Use when you are already inside an Effect program with an `McpServer`
|
|
2145
|
-
* service and need to add a concrete resource or URI-template resource
|
|
2146
|
-
* directly.
|
|
2147
|
-
*
|
|
2148
2290
|
* @see {@link resource} for the layer-based resource registration wrapper
|
|
2149
2291
|
*
|
|
2150
2292
|
* @stability unstable
|
|
@@ -2170,12 +2312,6 @@ export const registerResource: {
|
|
|
2170
2312
|
/**
|
|
2171
2313
|
* Registers an MCP resource or resource template from an Effect program.
|
|
2172
2314
|
*
|
|
2173
|
-
* **When to use**
|
|
2174
|
-
*
|
|
2175
|
-
* Use when you are already inside an Effect program with an `McpServer`
|
|
2176
|
-
* service and need to add a concrete resource or URI-template resource
|
|
2177
|
-
* directly.
|
|
2178
|
-
*
|
|
2179
2315
|
* @see {@link resource} for the layer-based resource registration wrapper
|
|
2180
2316
|
*
|
|
2181
2317
|
* @stability unstable
|
|
@@ -2206,9 +2342,7 @@ export const registerResource: {
|
|
|
2206
2342
|
| Schemas[number]["DecodingServices"]
|
|
2207
2343
|
| Schemas[number]["EncodingServices"]
|
|
2208
2344
|
| R
|
|
2209
|
-
|
|
|
2210
|
-
Ret extends Effect.Effect<infer _A, infer _E, infer _R> ? _R : never
|
|
2211
|
-
: never),
|
|
2345
|
+
| CompletionServices<Completions>,
|
|
2212
2346
|
McpRequestContext
|
|
2213
2347
|
>
|
|
2214
2348
|
| McpServer
|
|
@@ -2337,10 +2471,6 @@ export const registerResource: {
|
|
|
2337
2471
|
/**
|
|
2338
2472
|
* Creates a layer that registers an MCP resource or resource template.
|
|
2339
2473
|
*
|
|
2340
|
-
* **When to use**
|
|
2341
|
-
*
|
|
2342
|
-
* Use to compose resource registration into an MCP server layer.
|
|
2343
|
-
*
|
|
2344
2474
|
* @see {@link registerResource} for the Effect-level resource registration API
|
|
2345
2475
|
*
|
|
2346
2476
|
* @stability unstable
|
|
@@ -2351,10 +2481,6 @@ export const resource: {
|
|
|
2351
2481
|
/**
|
|
2352
2482
|
* Creates a layer that registers an MCP resource or resource template.
|
|
2353
2483
|
*
|
|
2354
|
-
* **When to use**
|
|
2355
|
-
*
|
|
2356
|
-
* Use to compose resource registration into an MCP server layer.
|
|
2357
|
-
*
|
|
2358
2484
|
* @see {@link registerResource} for the Effect-level resource registration API
|
|
2359
2485
|
*
|
|
2360
2486
|
* @stability unstable
|
|
@@ -2379,10 +2505,6 @@ export const resource: {
|
|
|
2379
2505
|
/**
|
|
2380
2506
|
* Creates a layer that registers an MCP resource or resource template.
|
|
2381
2507
|
*
|
|
2382
|
-
* **When to use**
|
|
2383
|
-
*
|
|
2384
|
-
* Use to compose resource registration into an MCP server layer.
|
|
2385
|
-
*
|
|
2386
2508
|
* @see {@link registerResource} for the Effect-level resource registration API
|
|
2387
2509
|
*
|
|
2388
2510
|
* @stability unstable
|
|
@@ -2409,10 +2531,10 @@ export const resource: {
|
|
|
2409
2531
|
never,
|
|
2410
2532
|
never,
|
|
2411
2533
|
Exclude<
|
|
2534
|
+
| Schemas[number]["DecodingServices"]
|
|
2535
|
+
| Schemas[number]["EncodingServices"]
|
|
2412
2536
|
| R
|
|
2413
|
-
|
|
|
2414
|
-
Ret extends Effect.Effect<infer _A, infer _E, infer _R> ? _R : never
|
|
2415
|
-
: never),
|
|
2537
|
+
| CompletionServices<Completions>,
|
|
2416
2538
|
McpRequestContext
|
|
2417
2539
|
>
|
|
2418
2540
|
>
|
|
@@ -2432,16 +2554,10 @@ export const resource: {
|
|
|
2432
2554
|
/**
|
|
2433
2555
|
* Registers an MCP prompt from an Effect program.
|
|
2434
2556
|
*
|
|
2435
|
-
* **When to use**
|
|
2436
|
-
*
|
|
2437
|
-
* Use when you are already inside an Effect program with an `McpServer`
|
|
2438
|
-
* service and need to add a prompt handler directly.
|
|
2439
|
-
*
|
|
2440
2557
|
* **Details**
|
|
2441
2558
|
*
|
|
2442
|
-
*
|
|
2443
|
-
*
|
|
2444
|
-
* text message.
|
|
2559
|
+
* Decodes parameters and encodes completion suggestions using their schemas.
|
|
2560
|
+
* String content becomes a user text message.
|
|
2445
2561
|
*
|
|
2446
2562
|
* @see {@link prompt} for the layer-based prompt registration wrapper
|
|
2447
2563
|
*
|
|
@@ -2476,6 +2592,7 @@ export const registerPrompt = <
|
|
|
2476
2592
|
never,
|
|
2477
2593
|
| Exclude<
|
|
2478
2594
|
| Schema.Struct.DecodingServices<Params>
|
|
2595
|
+
| Params[Extract<keyof Completions, keyof Params>]["EncodingServices"]
|
|
2479
2596
|
| R
|
|
2480
2597
|
| CompletionServices<Completions>,
|
|
2481
2598
|
McpRequestContext
|
|
@@ -2511,7 +2628,13 @@ export const registerPrompt = <
|
|
|
2511
2628
|
const registry = yield* McpServer
|
|
2512
2629
|
const services = omitRequestServices(
|
|
2513
2630
|
yield* Effect.context<
|
|
2514
|
-
Exclude<
|
|
2631
|
+
Exclude<
|
|
2632
|
+
| R
|
|
2633
|
+
| Schema.Struct.DecodingServices<Params>
|
|
2634
|
+
| Params[Extract<keyof Completions, keyof Params>]["EncodingServices"]
|
|
2635
|
+
| CompletionServices<Completions>,
|
|
2636
|
+
McpRequestContext
|
|
2637
|
+
>
|
|
2515
2638
|
>()
|
|
2516
2639
|
)
|
|
2517
2640
|
const completions: Record<
|
|
@@ -2577,16 +2700,6 @@ export const registerPrompt = <
|
|
|
2577
2700
|
/**
|
|
2578
2701
|
* Creates a layer that registers an MCP prompt.
|
|
2579
2702
|
*
|
|
2580
|
-
* **When to use**
|
|
2581
|
-
*
|
|
2582
|
-
* Use to compose prompt registration into an MCP server layer.
|
|
2583
|
-
*
|
|
2584
|
-
* **Details**
|
|
2585
|
-
*
|
|
2586
|
-
* Parameters are decoded with the supplied schema, completion handlers encode
|
|
2587
|
-
* per-parameter suggestions, and string prompt content is converted into a user
|
|
2588
|
-
* text message.
|
|
2589
|
-
*
|
|
2590
2703
|
* @see {@link registerPrompt} for the Effect-level prompt registration API
|
|
2591
2704
|
*
|
|
2592
2705
|
* @stability unstable
|
|
@@ -2620,6 +2733,7 @@ export const prompt = <
|
|
|
2620
2733
|
never,
|
|
2621
2734
|
Exclude<
|
|
2622
2735
|
| Schema.Struct.DecodingServices<Params>
|
|
2736
|
+
| Params[Extract<keyof Completions, keyof Params>]["EncodingServices"]
|
|
2623
2737
|
| R
|
|
2624
2738
|
| CompletionServices<Completions>,
|
|
2625
2739
|
McpRequestContext
|