@iworkforces/tracelattice 2.0.3
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/LICENSE +24 -0
- package/README.md +260 -0
- package/dist/CliLifecycle.d.ts +31 -0
- package/dist/CliLifecycle.d.ts.map +1 -0
- package/dist/CliLifecycle.js +90 -0
- package/dist/CliLifecycle.js.map +1 -0
- package/dist/ServerConfig.d.ts +290 -0
- package/dist/ServerConfig.d.ts.map +1 -0
- package/dist/ServerConfig.js +175 -0
- package/dist/ServerConfig.js.map +1 -0
- package/dist/cache/DiscoveryCache.d.ts +269 -0
- package/dist/cache/DiscoveryCache.d.ts.map +1 -0
- package/dist/cache/DiscoveryCache.js +104 -0
- package/dist/cache/DiscoveryCache.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +5177 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/ConfigLoader.d.ts +270 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +186 -0
- package/dist/config/ConfigLoader.js.map +1 -0
- package/dist/context/RequestContext.d.ts +43 -0
- package/dist/context/RequestContext.d.ts.map +1 -0
- package/dist/context/RequestContext.js +14 -0
- package/dist/context/RequestContext.js.map +1 -0
- package/dist/contracts/PersistenceBackend.d.ts +134 -0
- package/dist/contracts/PersistenceBackend.d.ts.map +1 -0
- package/dist/contracts/PersistenceBackend.js +6 -0
- package/dist/contracts/PersistenceBackend.js.map +1 -0
- package/dist/contracts/calibrator.d.ts +97 -0
- package/dist/contracts/calibrator.d.ts.map +1 -0
- package/dist/contracts/calibrator.js +1 -0
- package/dist/contracts/features.d.ts +35 -0
- package/dist/contracts/features.d.ts.map +1 -0
- package/dist/contracts/features.js +12 -0
- package/dist/contracts/features.js.map +1 -0
- package/dist/contracts/ids.d.ts +68 -0
- package/dist/contracts/ids.d.ts.map +1 -0
- package/dist/contracts/ids.js +40 -0
- package/dist/contracts/ids.js.map +1 -0
- package/dist/contracts/interfaces.d.ts +254 -0
- package/dist/contracts/interfaces.d.ts.map +1 -0
- package/dist/contracts/interfaces.js +1 -0
- package/dist/contracts/persistence-work.d.ts +96 -0
- package/dist/contracts/persistence-work.d.ts.map +1 -0
- package/dist/contracts/persistence-work.js +1 -0
- package/dist/contracts/reasoning-types.d.ts +21 -0
- package/dist/contracts/reasoning-types.d.ts.map +1 -0
- package/dist/contracts/reasoning-types.js +1 -0
- package/dist/contracts/strategy.d.ts +107 -0
- package/dist/contracts/strategy.d.ts.map +1 -0
- package/dist/contracts/strategy.js +1 -0
- package/dist/contracts/summary.d.ts +110 -0
- package/dist/contracts/summary.d.ts.map +1 -0
- package/dist/contracts/summary.js +1 -0
- package/dist/contracts/suspension.d.ts +215 -0
- package/dist/contracts/suspension.d.ts.map +1 -0
- package/dist/contracts/suspension.js +1 -0
- package/dist/contracts/transport.d.ts +26 -0
- package/dist/contracts/transport.d.ts.map +1 -0
- package/dist/contracts/transport.js +1 -0
- package/dist/core/CrossReferenceValidator.d.ts +18 -0
- package/dist/core/CrossReferenceValidator.d.ts.map +1 -0
- package/dist/core/CrossReferenceValidator.js +125 -0
- package/dist/core/CrossReferenceValidator.js.map +1 -0
- package/dist/core/HistoryManager.d.ts +215 -0
- package/dist/core/HistoryManager.d.ts.map +1 -0
- package/dist/core/HistoryManager.js +594 -0
- package/dist/core/HistoryManager.js.map +1 -0
- package/dist/core/IHistoryManager.d.ts +163 -0
- package/dist/core/IHistoryManager.d.ts.map +1 -0
- package/dist/core/IHistoryManager.js +1 -0
- package/dist/core/IThoughtFormatter.d.ts +51 -0
- package/dist/core/IThoughtFormatter.d.ts.map +1 -0
- package/dist/core/IThoughtFormatter.js +1 -0
- package/dist/core/InputNormalizer.d.ts +140 -0
- package/dist/core/InputNormalizer.d.ts.map +1 -0
- package/dist/core/InputNormalizer.js +95 -0
- package/dist/core/InputNormalizer.js.map +1 -0
- package/dist/core/PersistenceBuffer.d.ts +204 -0
- package/dist/core/PersistenceBuffer.d.ts.map +1 -0
- package/dist/core/PersistenceBuffer.js +382 -0
- package/dist/core/PersistenceBuffer.js.map +1 -0
- package/dist/core/PersistenceBufferErrors.d.ts +22 -0
- package/dist/core/PersistenceBufferErrors.d.ts.map +1 -0
- package/dist/core/PersistenceBufferErrors.js +30 -0
- package/dist/core/PersistenceBufferErrors.js.map +1 -0
- package/dist/core/PersistenceRestore.d.ts +21 -0
- package/dist/core/PersistenceRestore.d.ts.map +1 -0
- package/dist/core/PersistenceRestore.js +87 -0
- package/dist/core/PersistenceRestore.js.map +1 -0
- package/dist/core/PersistenceWorkQueue.d.ts +155 -0
- package/dist/core/PersistenceWorkQueue.d.ts.map +1 -0
- package/dist/core/PersistenceWorkQueue.js +298 -0
- package/dist/core/PersistenceWorkQueue.js.map +1 -0
- package/dist/core/PersistenceWriter.d.ts +55 -0
- package/dist/core/PersistenceWriter.d.ts.map +1 -0
- package/dist/core/PersistenceWriter.js +112 -0
- package/dist/core/PersistenceWriter.js.map +1 -0
- package/dist/core/SessionErrors.d.ts +37 -0
- package/dist/core/SessionErrors.d.ts.map +1 -0
- package/dist/core/SessionErrors.js +50 -0
- package/dist/core/SessionErrors.js.map +1 -0
- package/dist/core/SessionLifecycleCoordinator.d.ts +74 -0
- package/dist/core/SessionLifecycleCoordinator.d.ts.map +1 -0
- package/dist/core/SessionLifecycleCoordinator.js +222 -0
- package/dist/core/SessionLifecycleCoordinator.js.map +1 -0
- package/dist/core/SessionLock.d.ts +59 -0
- package/dist/core/SessionLock.d.ts.map +1 -0
- package/dist/core/SessionLock.js +39 -0
- package/dist/core/SessionLock.js.map +1 -0
- package/dist/core/SessionManager.d.ts +62 -0
- package/dist/core/SessionManager.d.ts.map +1 -0
- package/dist/core/SessionManager.js +75 -0
- package/dist/core/SessionManager.js.map +1 -0
- package/dist/core/SessionResetCoordinator.d.ts +37 -0
- package/dist/core/SessionResetCoordinator.d.ts.map +1 -0
- package/dist/core/SessionResetCoordinator.js +80 -0
- package/dist/core/SessionResetCoordinator.js.map +1 -0
- package/dist/core/ThoughtEvaluator.d.ts +48 -0
- package/dist/core/ThoughtEvaluator.d.ts.map +1 -0
- package/dist/core/ThoughtEvaluator.js +85 -0
- package/dist/core/ThoughtEvaluator.js.map +1 -0
- package/dist/core/ThoughtFormatter.d.ts +134 -0
- package/dist/core/ThoughtFormatter.d.ts.map +1 -0
- package/dist/core/ThoughtFormatter.js +118 -0
- package/dist/core/ThoughtFormatter.js.map +1 -0
- package/dist/core/ThoughtProcessor.d.ts +259 -0
- package/dist/core/ThoughtProcessor.d.ts.map +1 -0
- package/dist/core/ThoughtProcessor.js +451 -0
- package/dist/core/ThoughtProcessor.js.map +1 -0
- package/dist/core/ThoughtReferenceIndex.d.ts +23 -0
- package/dist/core/ThoughtReferenceIndex.d.ts.map +1 -0
- package/dist/core/ThoughtReferenceIndex.js +66 -0
- package/dist/core/ThoughtReferenceIndex.js.map +1 -0
- package/dist/core/VerificationOutcomeAdmission.d.ts +15 -0
- package/dist/core/VerificationOutcomeAdmission.d.ts.map +1 -0
- package/dist/core/VerificationOutcomeAdmission.js +28 -0
- package/dist/core/VerificationOutcomeAdmission.js.map +1 -0
- package/dist/core/compression/CompressionService.d.ts +76 -0
- package/dist/core/compression/CompressionService.d.ts.map +1 -0
- package/dist/core/compression/CompressionService.js +160 -0
- package/dist/core/compression/CompressionService.js.map +1 -0
- package/dist/core/compression/DehydrationPolicy.d.ts +75 -0
- package/dist/core/compression/DehydrationPolicy.d.ts.map +1 -0
- package/dist/core/compression/DehydrationPolicy.js +45 -0
- package/dist/core/compression/DehydrationPolicy.js.map +1 -0
- package/dist/core/compression/InMemorySummaryStore.d.ts +132 -0
- package/dist/core/compression/InMemorySummaryStore.d.ts.map +1 -0
- package/dist/core/compression/InMemorySummaryStore.js +69 -0
- package/dist/core/compression/InMemorySummaryStore.js.map +1 -0
- package/dist/core/compression/Summary.d.ts +74 -0
- package/dist/core/compression/Summary.d.ts.map +1 -0
- package/dist/core/compression/Summary.js +16 -0
- package/dist/core/compression/Summary.js.map +1 -0
- package/dist/core/evaluator/Aggregator.d.ts +40 -0
- package/dist/core/evaluator/Aggregator.d.ts.map +1 -0
- package/dist/core/evaluator/Aggregator.js +36 -0
- package/dist/core/evaluator/Aggregator.js.map +1 -0
- package/dist/core/evaluator/Calibrator.d.ts +52 -0
- package/dist/core/evaluator/Calibrator.d.ts.map +1 -0
- package/dist/core/evaluator/Calibrator.js +135 -0
- package/dist/core/evaluator/Calibrator.js.map +1 -0
- package/dist/core/evaluator/PatternDetector.d.ts +69 -0
- package/dist/core/evaluator/PatternDetector.d.ts.map +1 -0
- package/dist/core/evaluator/PatternDetector.js +192 -0
- package/dist/core/evaluator/PatternDetector.js.map +1 -0
- package/dist/core/evaluator/SignalComputer.d.ts +116 -0
- package/dist/core/evaluator/SignalComputer.d.ts.map +1 -0
- package/dist/core/evaluator/SignalComputer.js +110 -0
- package/dist/core/evaluator/SignalComputer.js.map +1 -0
- package/dist/core/evaluator/calibration-math.d.ts +39 -0
- package/dist/core/evaluator/calibration-math.d.ts.map +1 -0
- package/dist/core/evaluator/calibration-math.js +42 -0
- package/dist/core/evaluator/calibration-math.js.map +1 -0
- package/dist/core/evaluator/internals.d.ts +36 -0
- package/dist/core/evaluator/internals.d.ts.map +1 -0
- package/dist/core/evaluator/internals.js +43 -0
- package/dist/core/evaluator/internals.js.map +1 -0
- package/dist/core/graph/Edge.d.ts +58 -0
- package/dist/core/graph/Edge.d.ts.map +1 -0
- package/dist/core/graph/Edge.js +1 -0
- package/dist/core/graph/EdgeEmitter.d.ts +68 -0
- package/dist/core/graph/EdgeEmitter.d.ts.map +1 -0
- package/dist/core/graph/EdgeEmitter.js +118 -0
- package/dist/core/graph/EdgeEmitter.js.map +1 -0
- package/dist/core/graph/EdgeStore.d.ts +116 -0
- package/dist/core/graph/EdgeStore.d.ts.map +1 -0
- package/dist/core/graph/EdgeStore.js +107 -0
- package/dist/core/graph/EdgeStore.js.map +1 -0
- package/dist/core/graph/GraphView.d.ts +157 -0
- package/dist/core/graph/GraphView.d.ts.map +1 -0
- package/dist/core/graph/GraphView.js +149 -0
- package/dist/core/graph/GraphView.js.map +1 -0
- package/dist/core/ids.d.ts +33 -0
- package/dist/core/ids.d.ts.map +1 -0
- package/dist/core/ids.js +11 -0
- package/dist/core/ids.js.map +1 -0
- package/dist/core/reasoning/OutcomeRecorder.d.ts +88 -0
- package/dist/core/reasoning/OutcomeRecorder.d.ts.map +1 -0
- package/dist/core/reasoning/OutcomeRecorder.js +51 -0
- package/dist/core/reasoning/OutcomeRecorder.js.map +1 -0
- package/dist/core/reasoning/strategies/SequentialStrategy.d.ts +54 -0
- package/dist/core/reasoning/strategies/SequentialStrategy.d.ts.map +1 -0
- package/dist/core/reasoning/strategies/SequentialStrategy.js +22 -0
- package/dist/core/reasoning/strategies/SequentialStrategy.js.map +1 -0
- package/dist/core/reasoning/strategies/StrategyFactory.d.ts +25 -0
- package/dist/core/reasoning/strategies/StrategyFactory.d.ts.map +1 -0
- package/dist/core/reasoning/strategies/StrategyFactory.js +16 -0
- package/dist/core/reasoning/strategies/StrategyFactory.js.map +1 -0
- package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.d.ts +58 -0
- package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.d.ts.map +1 -0
- package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.js +103 -0
- package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.js.map +1 -0
- package/dist/core/reasoning/strategies/plateau.d.ts +18 -0
- package/dist/core/reasoning/strategies/plateau.d.ts.map +1 -0
- package/dist/core/reasoning/strategies/plateau.js +12 -0
- package/dist/core/reasoning/strategies/plateau.js.map +1 -0
- package/dist/core/reasoning/strategies/totScoring.d.ts +91 -0
- package/dist/core/reasoning/strategies/totScoring.d.ts.map +1 -0
- package/dist/core/reasoning/strategies/totScoring.js +88 -0
- package/dist/core/reasoning/strategies/totScoring.js.map +1 -0
- package/dist/core/reasoning.d.ts +179 -0
- package/dist/core/reasoning.d.ts.map +1 -0
- package/dist/core/reasoning.js +1 -0
- package/dist/core/step.d.ts +50 -0
- package/dist/core/step.d.ts.map +1 -0
- package/dist/core/step.js +1 -0
- package/dist/core/thought.d.ts +113 -0
- package/dist/core/thought.d.ts.map +1 -0
- package/dist/core/thought.js +1 -0
- package/dist/core/tools/InMemorySuspensionStore.d.ts +66 -0
- package/dist/core/tools/InMemorySuspensionStore.d.ts.map +1 -0
- package/dist/core/tools/InMemorySuspensionStore.js +121 -0
- package/dist/core/tools/InMemorySuspensionStore.js.map +1 -0
- package/dist/di/Container.d.ts +253 -0
- package/dist/di/Container.d.ts.map +1 -0
- package/dist/di/Container.js +111 -0
- package/dist/di/Container.js.map +1 -0
- package/dist/di/ServiceRegistry.d.ts +50 -0
- package/dist/di/ServiceRegistry.d.ts.map +1 -0
- package/dist/di/ServiceRegistry.js +1 -0
- package/dist/errors.d.ts +663 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +282 -0
- package/dist/errors.js.map +1 -0
- package/dist/health/HealthChecker.d.ts +73 -0
- package/dist/health/HealthChecker.d.ts.map +1 -0
- package/dist/health/HealthChecker.js +70 -0
- package/dist/health/HealthChecker.js.map +1 -0
- package/dist/lib.d.ts +273 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +409 -0
- package/dist/lib.js.map +1 -0
- package/dist/logger/NullLogger.d.ts +154 -0
- package/dist/logger/NullLogger.d.ts.map +1 -0
- package/dist/logger/NullLogger.js +24 -0
- package/dist/logger/NullLogger.js.map +1 -0
- package/dist/logger/StructuredLogger.d.ts +327 -0
- package/dist/logger/StructuredLogger.d.ts.map +1 -0
- package/dist/logger/StructuredLogger.js +72 -0
- package/dist/logger/StructuredLogger.js.map +1 -0
- package/dist/metrics/metrics.impl.d.ts +252 -0
- package/dist/metrics/metrics.impl.d.ts.map +1 -0
- package/dist/metrics/metrics.impl.js +197 -0
- package/dist/metrics/metrics.impl.js.map +1 -0
- package/dist/persistence/FileLegacyImport.d.ts +2 -0
- package/dist/persistence/FileLegacyImport.d.ts.map +1 -0
- package/dist/persistence/FileLegacyImport.js +183 -0
- package/dist/persistence/FileLegacyImport.js.map +1 -0
- package/dist/persistence/FilePersistence.d.ts +53 -0
- package/dist/persistence/FilePersistence.d.ts.map +1 -0
- package/dist/persistence/FilePersistence.js +312 -0
- package/dist/persistence/FilePersistence.js.map +1 -0
- package/dist/persistence/FileSnapshotTypes.d.ts +29 -0
- package/dist/persistence/FileSnapshotTypes.d.ts.map +1 -0
- package/dist/persistence/FileSnapshotTypes.js +1 -0
- package/dist/persistence/FileSnapshotV2.d.ts +377 -0
- package/dist/persistence/FileSnapshotV2.d.ts.map +1 -0
- package/dist/persistence/FileSnapshotV2.js +124 -0
- package/dist/persistence/FileSnapshotV2.js.map +1 -0
- package/dist/persistence/FileSnapshotValidation.d.ts +15 -0
- package/dist/persistence/FileSnapshotValidation.d.ts.map +1 -0
- package/dist/persistence/FileSnapshotValidation.js +64 -0
- package/dist/persistence/FileSnapshotValidation.js.map +1 -0
- package/dist/persistence/FileWriter.d.ts +30 -0
- package/dist/persistence/FileWriter.d.ts.map +1 -0
- package/dist/persistence/FileWriter.js +155 -0
- package/dist/persistence/FileWriter.js.map +1 -0
- package/dist/persistence/MemoryPersistence.d.ts +45 -0
- package/dist/persistence/MemoryPersistence.d.ts.map +1 -0
- package/dist/persistence/MemoryPersistence.js +180 -0
- package/dist/persistence/MemoryPersistence.js.map +1 -0
- package/dist/persistence/PersistenceCodec.d.ts +7 -0
- package/dist/persistence/PersistenceCodec.d.ts.map +1 -0
- package/dist/persistence/PersistenceCodec.js +97 -0
- package/dist/persistence/PersistenceCodec.js.map +1 -0
- package/dist/persistence/PersistenceErrors.d.ts +23 -0
- package/dist/persistence/PersistenceErrors.d.ts.map +1 -0
- package/dist/persistence/PersistenceErrors.js +26 -0
- package/dist/persistence/PersistenceErrors.js.map +1 -0
- package/dist/persistence/PersistenceFactory.d.ts +21 -0
- package/dist/persistence/PersistenceFactory.d.ts.map +1 -0
- package/dist/persistence/PersistenceFactory.js +28 -0
- package/dist/persistence/PersistenceFactory.js.map +1 -0
- package/dist/persistence/PersistenceScope.d.ts +42 -0
- package/dist/persistence/PersistenceScope.d.ts.map +1 -0
- package/dist/persistence/PersistenceScope.js +93 -0
- package/dist/persistence/PersistenceScope.js.map +1 -0
- package/dist/persistence/SessionScopedPersistence.d.ts +4 -0
- package/dist/persistence/SessionScopedPersistence.d.ts.map +1 -0
- package/dist/persistence/SessionScopedPersistence.js +9 -0
- package/dist/persistence/SessionScopedPersistence.js.map +1 -0
- package/dist/persistence/SqliteDriver.d.ts +22 -0
- package/dist/persistence/SqliteDriver.d.ts.map +1 -0
- package/dist/persistence/SqliteDriver.js +29 -0
- package/dist/persistence/SqliteDriver.js.map +1 -0
- package/dist/persistence/SqliteLegacyImport.d.ts +14 -0
- package/dist/persistence/SqliteLegacyImport.d.ts.map +1 -0
- package/dist/persistence/SqliteLegacyImport.js +136 -0
- package/dist/persistence/SqliteLegacyImport.js.map +1 -0
- package/dist/persistence/SqliteLegacySchema.d.ts +15 -0
- package/dist/persistence/SqliteLegacySchema.d.ts.map +1 -0
- package/dist/persistence/SqliteLegacySchema.js +72 -0
- package/dist/persistence/SqliteLegacySchema.js.map +1 -0
- package/dist/persistence/SqlitePayload.d.ts +11 -0
- package/dist/persistence/SqlitePayload.d.ts.map +1 -0
- package/dist/persistence/SqlitePayload.js +86 -0
- package/dist/persistence/SqlitePayload.js.map +1 -0
- package/dist/persistence/SqlitePersistence.d.ts +49 -0
- package/dist/persistence/SqlitePersistence.d.ts.map +1 -0
- package/dist/persistence/SqlitePersistence.js +248 -0
- package/dist/persistence/SqlitePersistence.js.map +1 -0
- package/dist/persistence/SqliteSchemaV2.d.ts +14 -0
- package/dist/persistence/SqliteSchemaV2.d.ts.map +1 -0
- package/dist/persistence/SqliteSchemaV2.js +129 -0
- package/dist/persistence/SqliteSchemaV2.js.map +1 -0
- package/dist/persistence/SqliteSnapshotWriter.d.ts +17 -0
- package/dist/persistence/SqliteSnapshotWriter.d.ts.map +1 -0
- package/dist/persistence/SqliteSnapshotWriter.js +30 -0
- package/dist/persistence/SqliteSnapshotWriter.js.map +1 -0
- package/dist/pool/ConnectionPool.d.ts +203 -0
- package/dist/pool/ConnectionPool.d.ts.map +1 -0
- package/dist/pool/ConnectionPool.js +303 -0
- package/dist/pool/ConnectionPool.js.map +1 -0
- package/dist/pool/IConnectionPool.d.ts +143 -0
- package/dist/pool/IConnectionPool.d.ts.map +1 -0
- package/dist/pool/IConnectionPool.js +1 -0
- package/dist/pool/PoolErrors.d.ts +11 -0
- package/dist/pool/PoolErrors.d.ts.map +1 -0
- package/dist/pool/PoolErrors.js +16 -0
- package/dist/pool/PoolErrors.js.map +1 -0
- package/dist/registry/BaseRegistry.d.ts +219 -0
- package/dist/registry/BaseRegistry.d.ts.map +1 -0
- package/dist/registry/BaseRegistry.js +215 -0
- package/dist/registry/BaseRegistry.js.map +1 -0
- package/dist/registry/SkillRegistry.d.ts +67 -0
- package/dist/registry/SkillRegistry.d.ts.map +1 -0
- package/dist/registry/SkillRegistry.js +87 -0
- package/dist/registry/SkillRegistry.js.map +1 -0
- package/dist/registry/ToolRegistry.d.ts +70 -0
- package/dist/registry/ToolRegistry.d.ts.map +1 -0
- package/dist/registry/ToolRegistry.js +96 -0
- package/dist/registry/ToolRegistry.js.map +1 -0
- package/dist/sanitize.d.ts +164 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +100 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/schema.d.ts +562 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +251 -0
- package/dist/schema.js.map +1 -0
- package/dist/transport/BaseTransport.d.ts +166 -0
- package/dist/transport/BaseTransport.d.ts.map +1 -0
- package/dist/transport/BaseTransport.js +199 -0
- package/dist/transport/BaseTransport.js.map +1 -0
- package/dist/transport/HttpHelpers.d.ts +53 -0
- package/dist/transport/HttpHelpers.d.ts.map +1 -0
- package/dist/transport/HttpHelpers.js +44 -0
- package/dist/transport/HttpHelpers.js.map +1 -0
- package/dist/transport/HttpRequestLifecycle.d.ts +37 -0
- package/dist/transport/HttpRequestLifecycle.d.ts.map +1 -0
- package/dist/transport/HttpRequestLifecycle.js +87 -0
- package/dist/transport/HttpRequestLifecycle.js.map +1 -0
- package/dist/transport/HttpTransport.d.ts +140 -0
- package/dist/transport/HttpTransport.d.ts.map +1 -0
- package/dist/transport/HttpTransport.js +245 -0
- package/dist/transport/HttpTransport.js.map +1 -0
- package/dist/transport/SseTransport.d.ts +149 -0
- package/dist/transport/SseTransport.d.ts.map +1 -0
- package/dist/transport/SseTransport.js +470 -0
- package/dist/transport/SseTransport.js.map +1 -0
- package/dist/transport/StreamableHttpTransport.d.ts +225 -0
- package/dist/transport/StreamableHttpTransport.d.ts.map +1 -0
- package/dist/transport/StreamableHttpTransport.js +449 -0
- package/dist/transport/StreamableHttpTransport.js.map +1 -0
- package/dist/types/disposable.d.ts +22 -0
- package/dist/types/disposable.d.ts.map +1 -0
- package/dist/types/disposable.js +1 -0
- package/dist/types/server-config.d.ts +32 -0
- package/dist/types/server-config.d.ts.map +1 -0
- package/dist/types/server-config.js +1 -0
- package/dist/types/skill.d.ts +74 -0
- package/dist/types/skill.d.ts.map +1 -0
- package/dist/types/skill.js +1 -0
- package/dist/types/tool.d.ts +78 -0
- package/dist/types/tool.d.ts.map +1 -0
- package/dist/types/tool.js +1 -0
- package/dist/utils.d.ts +27 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +6 -0
- package/dist/utils.js.map +1 -0
- package/dist/watchers/SkillWatcher.d.ts +25 -0
- package/dist/watchers/SkillWatcher.d.ts.map +1 -0
- package/dist/watchers/SkillWatcher.js +96 -0
- package/dist/watchers/SkillWatcher.js.map +1 -0
- package/dist/watchers/ToolWatcher.d.ts +24 -0
- package/dist/watchers/ToolWatcher.d.ts.map +1 -0
- package/dist/watchers/ToolWatcher.js +92 -0
- package/dist/watchers/ToolWatcher.js.map +1 -0
- package/package.json +106 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streamable HTTP Transport implementation (MCP spec recommended transport).
|
|
3
|
+
*
|
|
4
|
+
* This transport implements the MCP Streamable HTTP specification, which replaces
|
|
5
|
+
* the deprecated SSE transport as the recommended HTTP-based transport since March 2025.
|
|
6
|
+
*
|
|
7
|
+
* Key features:
|
|
8
|
+
* - POST /mcp for JSON-RPC requests (main MCP endpoint)
|
|
9
|
+
* - GET /mcp for optional SSE server-to-client notifications
|
|
10
|
+
* - Session management via Mcp-Session-Id header
|
|
11
|
+
* - Supports both stateful (session-based) and stateless (per-request) modes
|
|
12
|
+
* - Health endpoints (/health, /ready)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const transport = new StreamableHttpTransport({
|
|
17
|
+
* port: 3000,
|
|
18
|
+
* host: 'localhost',
|
|
19
|
+
* stateful: true,
|
|
20
|
+
* });
|
|
21
|
+
* await transport.connect(server);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
import type { McpServer } from 'tmcp';
|
|
25
|
+
import type { IMetrics } from '../contracts/interfaces.js';
|
|
26
|
+
import { BaseTransport, type TransportOptions } from './BaseTransport.js';
|
|
27
|
+
import type { ITransport, TransportKind } from '../contracts/transport.js';
|
|
28
|
+
/**
|
|
29
|
+
* MCP Streamable HTTP transport options extending base TransportOptions.
|
|
30
|
+
*/
|
|
31
|
+
export interface StreamableHttpTransportOptions extends TransportOptions {
|
|
32
|
+
/**
|
|
33
|
+
* Path for the MCP endpoint
|
|
34
|
+
* @default '/mcp'
|
|
35
|
+
*/
|
|
36
|
+
path?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Metrics collector for transport telemetry
|
|
39
|
+
*/
|
|
40
|
+
metrics?: IMetrics;
|
|
41
|
+
/**
|
|
42
|
+
* Prometheus metrics provider function
|
|
43
|
+
*/
|
|
44
|
+
metricsProvider?: () => string;
|
|
45
|
+
/**
|
|
46
|
+
* Enable stateful session-based mode.
|
|
47
|
+
* When true, sessions are tracked via Mcp-Session-Id header.
|
|
48
|
+
* When false, each request is processed independently (stateless).
|
|
49
|
+
* @default true
|
|
50
|
+
*/
|
|
51
|
+
stateful?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Custom session ID generator function.
|
|
54
|
+
* @default () => randomUUID()
|
|
55
|
+
*/
|
|
56
|
+
sessionIdGenerator?: () => string;
|
|
57
|
+
/**
|
|
58
|
+
* Enable request body size limit
|
|
59
|
+
* @default true
|
|
60
|
+
*/
|
|
61
|
+
enableBodySizeLimit?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Maximum request body size in bytes
|
|
64
|
+
* @default 10485760 (10MB)
|
|
65
|
+
*/
|
|
66
|
+
maxBodySize?: number;
|
|
67
|
+
/**
|
|
68
|
+
* Request timeout in milliseconds
|
|
69
|
+
* @default 30000 (30 seconds)
|
|
70
|
+
*/
|
|
71
|
+
requestTimeout?: number;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Streamable HTTP Transport for MCP server.
|
|
75
|
+
*
|
|
76
|
+
* This transport implements the MCP Streamable HTTP specification,
|
|
77
|
+
* providing JSON-RPC over HTTP with optional session management
|
|
78
|
+
* and server-to-client SSE notification streams.
|
|
79
|
+
*
|
|
80
|
+
* @remarks
|
|
81
|
+
* **Security Features (inherited from BaseTransport):**
|
|
82
|
+
* - Session ID validation (alphanumeric, max 64 chars)
|
|
83
|
+
* - Query parameter sanitization (whitelist allowed keys)
|
|
84
|
+
* - Rate limiting per IP (configurable, default 100 req/min)
|
|
85
|
+
* - CORS origin validation
|
|
86
|
+
* - Host header validation
|
|
87
|
+
*
|
|
88
|
+
* **MCP Streamable HTTP Spec Compliance:**
|
|
89
|
+
* - POST /mcp — JSON-RPC method calls
|
|
90
|
+
* - GET /mcp — SSE notification stream (server-to-client)
|
|
91
|
+
* - Mcp-Session-Id header for session management
|
|
92
|
+
* - Content-Type: application/json for JSON-RPC responses
|
|
93
|
+
* - Content-Type: text/event-stream for SSE notification streams
|
|
94
|
+
*
|
|
95
|
+
* **HTTP Status Code Mapping:**
|
|
96
|
+
* - 200: Success (JSON-RPC response or SSE stream)
|
|
97
|
+
* - 202: Accepted (JSON-RPC notification, no response body)
|
|
98
|
+
* - 204: CORS Preflight (empty body)
|
|
99
|
+
* - 400: Bad Request (invalid JSON, invalid session ID)
|
|
100
|
+
* - 403: Forbidden (invalid CORS, invalid host)
|
|
101
|
+
* - 404: Not Found
|
|
102
|
+
* - 405: Method Not Allowed
|
|
103
|
+
* - 413: Payload Too Large
|
|
104
|
+
* - 429: Too Many Requests
|
|
105
|
+
* - 500: Internal Server Error
|
|
106
|
+
* - 503: Server Not Ready / Shutting Down
|
|
107
|
+
*/
|
|
108
|
+
export declare class StreamableHttpTransport extends BaseTransport implements ITransport {
|
|
109
|
+
get kind(): TransportKind;
|
|
110
|
+
private _server;
|
|
111
|
+
private _mcpServer;
|
|
112
|
+
private _path;
|
|
113
|
+
private _stateful;
|
|
114
|
+
private _sessionIdGenerator;
|
|
115
|
+
private _sessions;
|
|
116
|
+
private _requestCount;
|
|
117
|
+
private _activeRequests;
|
|
118
|
+
private _bodySizeLimitEnabled;
|
|
119
|
+
private _maxBodySize;
|
|
120
|
+
private _requestTimeout;
|
|
121
|
+
private _metrics?;
|
|
122
|
+
private _metricsProvider;
|
|
123
|
+
private readonly _lifecycleFailureReporter;
|
|
124
|
+
private readonly _acceptedWork;
|
|
125
|
+
private _stopPromise;
|
|
126
|
+
constructor(options?: StreamableHttpTransportOptions);
|
|
127
|
+
private _requireMcpServer;
|
|
128
|
+
/**
|
|
129
|
+
* Get number of active sessions (stateful) or active requests (stateless).
|
|
130
|
+
*/
|
|
131
|
+
get clientCount(): number;
|
|
132
|
+
/**
|
|
133
|
+
* Get the total number of requests handled.
|
|
134
|
+
*/
|
|
135
|
+
get requestCount(): number;
|
|
136
|
+
/**
|
|
137
|
+
* Connects MCP server to this transport and starts listening.
|
|
138
|
+
*/
|
|
139
|
+
connect(mcpServer: McpServer): Promise<void>;
|
|
140
|
+
/**
|
|
141
|
+
* Route and handle incoming HTTP requests.
|
|
142
|
+
*/
|
|
143
|
+
private _handleRequest;
|
|
144
|
+
/**
|
|
145
|
+
* Send a JSON-RPC error response.
|
|
146
|
+
*/
|
|
147
|
+
private _sendJsonRpcError;
|
|
148
|
+
/**
|
|
149
|
+
* Handle POST /mcp — JSON-RPC method calls.
|
|
150
|
+
*
|
|
151
|
+
* Per the MCP Streamable HTTP spec:
|
|
152
|
+
* - Accepts JSON-RPC request bodies
|
|
153
|
+
* - Returns Mcp-Session-Id header for new sessions (stateful mode)
|
|
154
|
+
* - Validates Mcp-Session-Id for existing sessions (stateful mode)
|
|
155
|
+
* - Content-Type: application/json for responses
|
|
156
|
+
*/
|
|
157
|
+
private _handleMcpPost;
|
|
158
|
+
private _receiveAndFinalize;
|
|
159
|
+
/**
|
|
160
|
+
* Handle GET /mcp — Optional SSE notification stream.
|
|
161
|
+
*
|
|
162
|
+
* Per the MCP Streamable HTTP spec, clients may open a GET request
|
|
163
|
+
* to receive server-initiated notifications as SSE events.
|
|
164
|
+
* Requires a valid Mcp-Session-Id in stateful mode.
|
|
165
|
+
*/
|
|
166
|
+
private _handleMcpGet;
|
|
167
|
+
/**
|
|
168
|
+
* Resolve or create a session for a stateful request.
|
|
169
|
+
*
|
|
170
|
+
* @returns Session ID string on success, or the response error to finalize.
|
|
171
|
+
*/
|
|
172
|
+
private _resolveSession;
|
|
173
|
+
/**
|
|
174
|
+
* Extract Mcp-Session-Id from request headers.
|
|
175
|
+
*/
|
|
176
|
+
private _getSessionIdFromHeader;
|
|
177
|
+
/**
|
|
178
|
+
* Send an SSE event to a specific client response stream.
|
|
179
|
+
*/
|
|
180
|
+
private _sendSseEvent;
|
|
181
|
+
/**
|
|
182
|
+
* Broadcast a notification to all SSE streams in a given session.
|
|
183
|
+
*
|
|
184
|
+
* @param sessionId - Target session ID
|
|
185
|
+
* @param event - SSE event name
|
|
186
|
+
* @param data - Event payload
|
|
187
|
+
*/
|
|
188
|
+
broadcastToSession(sessionId: string, event: string, data: unknown): void;
|
|
189
|
+
/**
|
|
190
|
+
* Handle GET /metrics endpoint.
|
|
191
|
+
*/
|
|
192
|
+
private _handleMetrics;
|
|
193
|
+
/**
|
|
194
|
+
* Handle GET /health — Liveness check.
|
|
195
|
+
*/
|
|
196
|
+
private _handleHealthCheck;
|
|
197
|
+
/**
|
|
198
|
+
* Handle GET /ready — Readiness check.
|
|
199
|
+
*/
|
|
200
|
+
private _handleReadinessCheck;
|
|
201
|
+
/**
|
|
202
|
+
* Update session-related metrics.
|
|
203
|
+
*/
|
|
204
|
+
private _updateSessionMetrics;
|
|
205
|
+
/**
|
|
206
|
+
* Stop transport server with graceful shutdown.
|
|
207
|
+
*
|
|
208
|
+
* @param timeout - Maximum time before force-closing HTTP connections (default: 30s)
|
|
209
|
+
*/
|
|
210
|
+
stop(timeout?: number): Promise<void>;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Create a Streamable HTTP transport with given options.
|
|
214
|
+
*
|
|
215
|
+
* @param options - Transport configuration
|
|
216
|
+
* @returns A configured Streamable HTTP transport
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```typescript
|
|
220
|
+
* const transport = createStreamableHttpTransport({ port: 3000, stateful: true });
|
|
221
|
+
* await transport.connect(server);
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
export declare function createStreamableHttpTransport(options?: StreamableHttpTransportOptions): StreamableHttpTransport;
|
|
225
|
+
//# sourceMappingURL=StreamableHttpTransport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamableHttpTransport.d.ts","sourceRoot":"","sources":["../../src/transport/StreamableHttpTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAG3D,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAU3E;;GAEG;AACH,MAAM,WAAW,8BAA+B,SAAQ,gBAAgB;IACvE;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC;IAEnB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;IAE/B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,MAAM,CAAC;IAElC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAsBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,uBAAwB,SAAQ,aAAc,YAAW,UAAU;IAC/E,IAAI,IAAI,IAAI,aAAa,CAExB;IACD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,mBAAmB,CAAe;IAC1C,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,qBAAqB,CAAU;IACvC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,CAAW;IAC5B,OAAO,CAAC,gBAAgB,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAA2B;IACrE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB;IACpD,OAAO,CAAC,YAAY,CAA8B;gBAEtC,OAAO,GAAE,8BAAmC;IAmBxD,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;OAEG;IACG,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IA2ClD;;OAEG;YACW,cAAc;IA+F5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;;;OAQG;YACW,cAAc;YAqGd,mBAAmB;IAwBjC;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAsErB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAuCvB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAQ/B;;OAEG;IACH,OAAO,CAAC,aAAa;IASrB;;;;;;OAMG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAWzE;;OAEG;IACH,OAAO,CAAC,cAAc;IAWtB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;YACW,qBAAqB;IAkBnC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;;;OAIG;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAyDrC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAC5C,OAAO,GAAE,8BAAmC,GAC1C,uBAAuB,CAEzB"}
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { safeParse } from "valibot";
|
|
4
|
+
import { getErrorMessage } from "../errors.js";
|
|
5
|
+
import { JsonRpcRequestSchema } from "../schema.js";
|
|
6
|
+
import { BaseTransport } from "./BaseTransport.js";
|
|
7
|
+
import { asSessionId } from "../contracts/ids.js";
|
|
8
|
+
import { readRequestBody } from "./HttpHelpers.js";
|
|
9
|
+
import { runWithContext } from "../context/RequestContext.js";
|
|
10
|
+
import { AcceptedWorkTracker, LifecycleFailureReporter, ResponseFinalizer } from "./HttpRequestLifecycle.js";
|
|
11
|
+
class StreamableHttpTransport extends BaseTransport {
|
|
12
|
+
get kind() {
|
|
13
|
+
return 'streamable-http';
|
|
14
|
+
}
|
|
15
|
+
_server = null;
|
|
16
|
+
_mcpServer = null;
|
|
17
|
+
_path;
|
|
18
|
+
_stateful;
|
|
19
|
+
_sessionIdGenerator;
|
|
20
|
+
_sessions = new Map();
|
|
21
|
+
_requestCount = 0;
|
|
22
|
+
_activeRequests = 0;
|
|
23
|
+
_bodySizeLimitEnabled;
|
|
24
|
+
_maxBodySize;
|
|
25
|
+
_requestTimeout;
|
|
26
|
+
_metrics;
|
|
27
|
+
_metricsProvider;
|
|
28
|
+
_lifecycleFailureReporter;
|
|
29
|
+
_acceptedWork;
|
|
30
|
+
_stopPromise = null;
|
|
31
|
+
constructor(options = {}){
|
|
32
|
+
super(options);
|
|
33
|
+
this._path = options.path ?? '/mcp';
|
|
34
|
+
this._stateful = options.stateful ?? true;
|
|
35
|
+
this._sessionIdGenerator = options.sessionIdGenerator ?? (()=>randomUUID());
|
|
36
|
+
this._bodySizeLimitEnabled = options.enableBodySizeLimit ?? true;
|
|
37
|
+
this._maxBodySize = options.maxBodySize ?? 10485760;
|
|
38
|
+
this._requestTimeout = options.requestTimeout ?? 30000;
|
|
39
|
+
this._metrics = options.metrics;
|
|
40
|
+
this._metricsProvider = options.metricsProvider ?? null;
|
|
41
|
+
this._lifecycleFailureReporter = new LifecycleFailureReporter((error)=>{
|
|
42
|
+
this.log('error', 'Streamable HTTP request lifecycle failed', {
|
|
43
|
+
error: getErrorMessage(error)
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
this._acceptedWork = new AcceptedWorkTracker(this._lifecycleFailureReporter);
|
|
47
|
+
}
|
|
48
|
+
_requireMcpServer() {
|
|
49
|
+
if (!this._mcpServer) throw new Error('MCP server not initialized. Did you call connect()?');
|
|
50
|
+
return this._mcpServer;
|
|
51
|
+
}
|
|
52
|
+
get clientCount() {
|
|
53
|
+
return this._stateful ? this._sessions.size : this._activeRequests;
|
|
54
|
+
}
|
|
55
|
+
get requestCount() {
|
|
56
|
+
return this._requestCount;
|
|
57
|
+
}
|
|
58
|
+
async connect(mcpServer) {
|
|
59
|
+
this._mcpServer = mcpServer;
|
|
60
|
+
const server = createServer((req, res)=>{
|
|
61
|
+
const responseFinalizer = new ResponseFinalizer(res, this._lifecycleFailureReporter);
|
|
62
|
+
this._handleRequest(req, res).catch((error)=>{
|
|
63
|
+
this._lifecycleFailureReporter.report(error);
|
|
64
|
+
responseFinalizer.finalize((response)=>{
|
|
65
|
+
this._sendJsonRpcError(response, 500, -32603, 'Internal error', null, {
|
|
66
|
+
data: getErrorMessage(error)
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
this._server = server;
|
|
72
|
+
return new Promise((resolve, reject)=>{
|
|
73
|
+
const cleanup = ()=>{
|
|
74
|
+
server.off('error', onError);
|
|
75
|
+
server.off('listening', onListening);
|
|
76
|
+
};
|
|
77
|
+
const onError = (error)=>{
|
|
78
|
+
cleanup();
|
|
79
|
+
reject(error);
|
|
80
|
+
};
|
|
81
|
+
const onListening = ()=>{
|
|
82
|
+
cleanup();
|
|
83
|
+
this.log('info', `Streamable HTTP transport listening on http://${this._host}:${this._port}`);
|
|
84
|
+
resolve();
|
|
85
|
+
};
|
|
86
|
+
server.once('error', onError);
|
|
87
|
+
server.once('listening', onListening);
|
|
88
|
+
try {
|
|
89
|
+
server.listen(this._port, this._host);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
cleanup();
|
|
92
|
+
reject(error);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
async _handleRequest(req, res) {
|
|
97
|
+
const startTime = Date.now();
|
|
98
|
+
this._metrics?.counter('streamable_http_requests_total', 1, {}, 'Total Streamable HTTP transport requests');
|
|
99
|
+
res.once('finish', ()=>{
|
|
100
|
+
const durationSeconds = (Date.now() - startTime) / 1000;
|
|
101
|
+
this._metrics?.histogram('streamable_http_request_duration_seconds', durationSeconds, {});
|
|
102
|
+
});
|
|
103
|
+
if (!this.validateHostHeader(req)) return void this._sendJsonRpcError(res, 403, -32000, 'Forbidden - invalid host header');
|
|
104
|
+
if (this.isShuttingDown) return void this._sendJsonRpcError(res, 503, -32603, 'Server is shutting down');
|
|
105
|
+
const clientIp = this.getClientIp(req);
|
|
106
|
+
if (this.checkRateLimit(clientIp)) {
|
|
107
|
+
res.setHeader('Retry-After', '60');
|
|
108
|
+
this._sendJsonRpcError(res, 429, -32000, 'Too many requests');
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (!this.validateCorsOrigin(req)) return void this._sendJsonRpcError(res, 403, -32000, 'Forbidden - invalid origin');
|
|
112
|
+
this.setCorsHeaders(res);
|
|
113
|
+
if ('OPTIONS' === req.method) {
|
|
114
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Mcp-Session-Id');
|
|
115
|
+
res.writeHead(204);
|
|
116
|
+
res.end();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const urlPath = req.url?.split('?')[0] ?? '/';
|
|
120
|
+
if ('GET' === req.method && '/metrics' === urlPath) return void this._handleMetrics(res);
|
|
121
|
+
if ('GET' === req.method && '/health' === urlPath) return void this._handleHealthCheck(res);
|
|
122
|
+
if ('GET' === req.method && '/ready' === urlPath) return void await this._handleReadinessCheck(res);
|
|
123
|
+
if (urlPath === this._path) {
|
|
124
|
+
if ('POST' === req.method) return void this._acceptedWork.track(this._handleMcpPost(req, res));
|
|
125
|
+
if ('GET' === req.method) return void this._handleMcpGet(req, res);
|
|
126
|
+
res.writeHead(405, {
|
|
127
|
+
'Content-Type': 'application/json',
|
|
128
|
+
Allow: 'GET, POST'
|
|
129
|
+
});
|
|
130
|
+
res.end(JSON.stringify({
|
|
131
|
+
jsonrpc: '2.0',
|
|
132
|
+
id: null,
|
|
133
|
+
error: {
|
|
134
|
+
code: -32601,
|
|
135
|
+
message: 'Method not allowed'
|
|
136
|
+
}
|
|
137
|
+
}));
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
this._sendJsonRpcError(res, 404, -32601, 'Not Found');
|
|
141
|
+
}
|
|
142
|
+
_sendJsonRpcError(res, statusCode, code, message, id = null, extra) {
|
|
143
|
+
const error = {
|
|
144
|
+
code,
|
|
145
|
+
message
|
|
146
|
+
};
|
|
147
|
+
if (extra) Object.assign(error, extra);
|
|
148
|
+
res.writeHead(statusCode, {
|
|
149
|
+
'Content-Type': 'application/json'
|
|
150
|
+
});
|
|
151
|
+
res.end(JSON.stringify({
|
|
152
|
+
jsonrpc: '2.0',
|
|
153
|
+
id,
|
|
154
|
+
error
|
|
155
|
+
}));
|
|
156
|
+
}
|
|
157
|
+
async _handleMcpPost(req, res) {
|
|
158
|
+
this._requestCount++;
|
|
159
|
+
this._activeRequests++;
|
|
160
|
+
const responseFinalizer = new ResponseFinalizer(res, this._lifecycleFailureReporter);
|
|
161
|
+
const timeout = setTimeout(()=>{
|
|
162
|
+
responseFinalizer.finalize((response)=>{
|
|
163
|
+
this._sendJsonRpcError(response, 500, -32603, 'Request timeout');
|
|
164
|
+
});
|
|
165
|
+
}, this._requestTimeout);
|
|
166
|
+
try {
|
|
167
|
+
const body = await readRequestBody(req, this._bodySizeLimitEnabled ? this._maxBodySize : 0);
|
|
168
|
+
if (null === body) return void responseFinalizer.finalize((response)=>{
|
|
169
|
+
this._sendJsonRpcError(response, 413, -32000, 'Request body too large');
|
|
170
|
+
});
|
|
171
|
+
let rawBody;
|
|
172
|
+
try {
|
|
173
|
+
rawBody = JSON.parse(body);
|
|
174
|
+
} catch {
|
|
175
|
+
responseFinalizer.finalize((response)=>{
|
|
176
|
+
this._sendJsonRpcError(response, 200, -32700, 'Parse error');
|
|
177
|
+
});
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const parseResult = safeParse(JsonRpcRequestSchema, rawBody);
|
|
181
|
+
const rawId = rawBody && 'object' == typeof rawBody && 'id' in rawBody ? rawBody.id ?? null : null;
|
|
182
|
+
if (!parseResult.success) return void responseFinalizer.finalize((response)=>{
|
|
183
|
+
this._sendJsonRpcError(response, 200, -32600, 'Invalid Request', rawId, {
|
|
184
|
+
data: parseResult.issues
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
const jsonRpcRequest = parseResult.output;
|
|
188
|
+
let sessionId;
|
|
189
|
+
if (this._stateful) {
|
|
190
|
+
const sessionResult = this._resolveSession(req);
|
|
191
|
+
if ('string' != typeof sessionResult) return void responseFinalizer.finalize((response)=>{
|
|
192
|
+
this._sendJsonRpcError(response, sessionResult.statusCode, sessionResult.code, sessionResult.message);
|
|
193
|
+
});
|
|
194
|
+
sessionId = sessionResult;
|
|
195
|
+
}
|
|
196
|
+
if (!this._mcpServer) return void responseFinalizer.finalize((response)=>{
|
|
197
|
+
this._sendJsonRpcError(response, 503, -32603, 'Server not ready', jsonRpcRequest?.id ?? null);
|
|
198
|
+
});
|
|
199
|
+
await this._receiveAndFinalize(jsonRpcRequest, sessionId, responseFinalizer);
|
|
200
|
+
} catch (error) {
|
|
201
|
+
responseFinalizer.finalize((response)=>{
|
|
202
|
+
this._sendJsonRpcError(response, 200, -32603, 'Internal error', null, {
|
|
203
|
+
data: getErrorMessage(error)
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
} finally{
|
|
207
|
+
clearTimeout(timeout);
|
|
208
|
+
this._activeRequests--;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async _receiveAndFinalize(jsonRpcRequest, sessionId, responseFinalizer) {
|
|
212
|
+
const owner = this._stateful ? sessionId ?? randomUUID() : randomUUID();
|
|
213
|
+
const response = await runWithContext({
|
|
214
|
+
requestId: randomUUID(),
|
|
215
|
+
owner
|
|
216
|
+
}, ()=>this._requireMcpServer().receive(jsonRpcRequest, {
|
|
217
|
+
sessionInfo: {}
|
|
218
|
+
}));
|
|
219
|
+
const responseHeaders = {
|
|
220
|
+
'Content-Type': 'application/json'
|
|
221
|
+
};
|
|
222
|
+
if (sessionId) responseHeaders['Mcp-Session-Id'] = sessionId;
|
|
223
|
+
responseFinalizer.finalize((httpResponse)=>{
|
|
224
|
+
if (response) {
|
|
225
|
+
httpResponse.writeHead(200, responseHeaders);
|
|
226
|
+
httpResponse.end(JSON.stringify(response));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (sessionId) httpResponse.setHeader('Mcp-Session-Id', sessionId);
|
|
230
|
+
httpResponse.writeHead(202);
|
|
231
|
+
httpResponse.end();
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
_handleMcpGet(req, res) {
|
|
235
|
+
if (!this._stateful) {
|
|
236
|
+
res.writeHead(405, {
|
|
237
|
+
'Content-Type': 'application/json',
|
|
238
|
+
Allow: 'POST'
|
|
239
|
+
});
|
|
240
|
+
res.end(JSON.stringify({
|
|
241
|
+
jsonrpc: '2.0',
|
|
242
|
+
id: null,
|
|
243
|
+
error: {
|
|
244
|
+
code: -32601,
|
|
245
|
+
message: 'GET not supported in stateless mode'
|
|
246
|
+
}
|
|
247
|
+
}));
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const sessionId = this._getSessionIdFromHeader(req);
|
|
251
|
+
if (!sessionId) {
|
|
252
|
+
res.writeHead(400, {
|
|
253
|
+
'Content-Type': 'application/json'
|
|
254
|
+
});
|
|
255
|
+
res.end(JSON.stringify({
|
|
256
|
+
jsonrpc: '2.0',
|
|
257
|
+
id: null,
|
|
258
|
+
error: {
|
|
259
|
+
code: -32600,
|
|
260
|
+
message: 'Missing Mcp-Session-Id header'
|
|
261
|
+
}
|
|
262
|
+
}));
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const session = this._sessions.get(asSessionId(sessionId));
|
|
266
|
+
if (!session) {
|
|
267
|
+
res.writeHead(404, {
|
|
268
|
+
'Content-Type': 'application/json'
|
|
269
|
+
});
|
|
270
|
+
res.end(JSON.stringify({
|
|
271
|
+
jsonrpc: '2.0',
|
|
272
|
+
id: null,
|
|
273
|
+
error: {
|
|
274
|
+
code: -32001,
|
|
275
|
+
message: 'Session not found'
|
|
276
|
+
}
|
|
277
|
+
}));
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
res.writeHead(200, {
|
|
281
|
+
'Content-Type': 'text/event-stream',
|
|
282
|
+
'Cache-Control': 'no-cache',
|
|
283
|
+
Connection: 'keep-alive',
|
|
284
|
+
'Mcp-Session-Id': sessionId
|
|
285
|
+
});
|
|
286
|
+
this._sendSseEvent(res, 'connected', {
|
|
287
|
+
sessionId,
|
|
288
|
+
timestamp: Date.now()
|
|
289
|
+
});
|
|
290
|
+
session.notificationStreams.add(res);
|
|
291
|
+
session.lastActivityAt = Date.now();
|
|
292
|
+
this._updateSessionMetrics();
|
|
293
|
+
req.on('close', ()=>{
|
|
294
|
+
session.notificationStreams.delete(res);
|
|
295
|
+
this._updateSessionMetrics();
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
_resolveSession(req) {
|
|
299
|
+
const headerSessionId = this._getSessionIdFromHeader(req);
|
|
300
|
+
if (headerSessionId) {
|
|
301
|
+
if (!this.validateSessionId(headerSessionId)) return {
|
|
302
|
+
statusCode: 400,
|
|
303
|
+
code: -32600,
|
|
304
|
+
message: 'Invalid Mcp-Session-Id format'
|
|
305
|
+
};
|
|
306
|
+
const session = this._sessions.get(asSessionId(headerSessionId));
|
|
307
|
+
if (session) {
|
|
308
|
+
session.lastActivityAt = Date.now();
|
|
309
|
+
return headerSessionId;
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
statusCode: 404,
|
|
313
|
+
code: -32001,
|
|
314
|
+
message: 'Session not found'
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
const newSessionId = this._sessionIdGenerator();
|
|
318
|
+
const sessionState = {
|
|
319
|
+
id: newSessionId,
|
|
320
|
+
createdAt: Date.now(),
|
|
321
|
+
lastActivityAt: Date.now(),
|
|
322
|
+
notificationStreams: new Set()
|
|
323
|
+
};
|
|
324
|
+
this._sessions.set(asSessionId(newSessionId), sessionState);
|
|
325
|
+
this.log('info', `New session created: ${newSessionId}`);
|
|
326
|
+
this._updateSessionMetrics();
|
|
327
|
+
return newSessionId;
|
|
328
|
+
}
|
|
329
|
+
_getSessionIdFromHeader(req) {
|
|
330
|
+
const value = req.headers['mcp-session-id'];
|
|
331
|
+
if ('string' == typeof value && value.length > 0) return value;
|
|
332
|
+
}
|
|
333
|
+
_sendSseEvent(res, event, data) {
|
|
334
|
+
try {
|
|
335
|
+
res.write(`event: ${event}\n`);
|
|
336
|
+
res.write(`data: ${JSON.stringify(data)}\n\n`);
|
|
337
|
+
} catch {}
|
|
338
|
+
}
|
|
339
|
+
broadcastToSession(sessionId, event, data) {
|
|
340
|
+
const session = this._sessions.get(asSessionId(sessionId));
|
|
341
|
+
if (!session) return;
|
|
342
|
+
for (const stream of session.notificationStreams)this._sendSseEvent(stream, event, data);
|
|
343
|
+
}
|
|
344
|
+
_handleMetrics(res) {
|
|
345
|
+
if (!this._metricsProvider) {
|
|
346
|
+
res.writeHead(404, {
|
|
347
|
+
'Content-Type': 'text/plain'
|
|
348
|
+
});
|
|
349
|
+
res.end('Not Found');
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
res.writeHead(200, {
|
|
353
|
+
'Content-Type': 'text/plain; version=0.0.4; charset=utf-8'
|
|
354
|
+
});
|
|
355
|
+
res.end(this._metricsProvider());
|
|
356
|
+
}
|
|
357
|
+
_handleHealthCheck(res) {
|
|
358
|
+
const healthData = {
|
|
359
|
+
status: 'healthy',
|
|
360
|
+
requests: this._requestCount,
|
|
361
|
+
sessions: this._sessions.size,
|
|
362
|
+
transport: 'streamable-http'
|
|
363
|
+
};
|
|
364
|
+
if (this._healthChecker) {
|
|
365
|
+
const liveness = this._healthChecker.checkLiveness();
|
|
366
|
+
healthData.liveness = liveness;
|
|
367
|
+
}
|
|
368
|
+
res.writeHead(200, {
|
|
369
|
+
'Content-Type': 'application/json'
|
|
370
|
+
});
|
|
371
|
+
res.end(JSON.stringify(healthData));
|
|
372
|
+
}
|
|
373
|
+
async _handleReadinessCheck(res) {
|
|
374
|
+
if (this._healthChecker) {
|
|
375
|
+
const readiness = await this._healthChecker.checkReadiness();
|
|
376
|
+
const statusCode = 'ok' === readiness.status ? 200 : 503;
|
|
377
|
+
res.writeHead(statusCode, {
|
|
378
|
+
'Content-Type': 'application/json'
|
|
379
|
+
});
|
|
380
|
+
res.end(JSON.stringify(readiness));
|
|
381
|
+
} else {
|
|
382
|
+
res.writeHead(200, {
|
|
383
|
+
'Content-Type': 'application/json'
|
|
384
|
+
});
|
|
385
|
+
res.end(JSON.stringify({
|
|
386
|
+
status: 'ok',
|
|
387
|
+
timestamp: new Date().toISOString(),
|
|
388
|
+
components: {}
|
|
389
|
+
}));
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
_updateSessionMetrics() {
|
|
393
|
+
this._metrics?.gauge('streamable_http_active_sessions', this._sessions.size, {}, 'Active Streamable HTTP sessions');
|
|
394
|
+
let totalStreams = 0;
|
|
395
|
+
for (const session of this._sessions.values())totalStreams += session.notificationStreams.size;
|
|
396
|
+
this._metrics?.gauge('streamable_http_notification_streams', totalStreams, {}, 'Active SSE notification streams');
|
|
397
|
+
}
|
|
398
|
+
stop(timeout) {
|
|
399
|
+
if (this._stopPromise) return this._stopPromise;
|
|
400
|
+
this._isShuttingDown = true;
|
|
401
|
+
this._stopRateLimitCleanup();
|
|
402
|
+
const shutdownTimeout = timeout ?? 30000;
|
|
403
|
+
for (const session of this._sessions.values()){
|
|
404
|
+
for (const stream of session.notificationStreams)try {
|
|
405
|
+
stream.end();
|
|
406
|
+
} catch {}
|
|
407
|
+
session.notificationStreams.clear();
|
|
408
|
+
}
|
|
409
|
+
this._sessions.clear();
|
|
410
|
+
const server = this._server;
|
|
411
|
+
const serverClosed = new Promise((resolve, reject)=>{
|
|
412
|
+
if (!server?.listening) return void resolve();
|
|
413
|
+
let settled = false;
|
|
414
|
+
let forceClose = null;
|
|
415
|
+
server.close((error)=>{
|
|
416
|
+
if (settled) return;
|
|
417
|
+
settled = true;
|
|
418
|
+
if (forceClose) clearTimeout(forceClose);
|
|
419
|
+
if (error) return void reject(error);
|
|
420
|
+
resolve();
|
|
421
|
+
});
|
|
422
|
+
if (settled) return;
|
|
423
|
+
forceClose = setTimeout(()=>{
|
|
424
|
+
if (settled) return;
|
|
425
|
+
settled = true;
|
|
426
|
+
this.log('warn', 'Streamable HTTP transport force-closing after timeout');
|
|
427
|
+
server.closeAllConnections();
|
|
428
|
+
resolve();
|
|
429
|
+
}, shutdownTimeout);
|
|
430
|
+
});
|
|
431
|
+
const stopPromise = Promise.all([
|
|
432
|
+
serverClosed,
|
|
433
|
+
this._acceptedWork.join()
|
|
434
|
+
]).then(()=>{
|
|
435
|
+
this.log('info', 'Streamable HTTP transport stopped');
|
|
436
|
+
});
|
|
437
|
+
this._stopPromise = stopPromise;
|
|
438
|
+
stopPromise.catch(()=>{
|
|
439
|
+
if (this._stopPromise === stopPromise) this._stopPromise = null;
|
|
440
|
+
});
|
|
441
|
+
return stopPromise;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
function createStreamableHttpTransport(options = {}) {
|
|
445
|
+
return new StreamableHttpTransport(options);
|
|
446
|
+
}
|
|
447
|
+
export { StreamableHttpTransport, createStreamableHttpTransport };
|
|
448
|
+
|
|
449
|
+
//# sourceMappingURL=StreamableHttpTransport.js.map
|