@cyanheads/mcp-ts-core 0.11.5 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +27 -23
- package/CLAUDE.md +27 -23
- package/README.md +10 -10
- package/biome.json +1 -1
- package/changelog/0.12.x/0.12.0.md +96 -0
- package/dist/cli/init.js +1 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/config/index.d.ts +0 -18
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +0 -25
- package/dist/config/index.js.map +1 -1
- package/dist/core/app.d.ts +5 -7
- package/dist/core/app.d.ts.map +1 -1
- package/dist/core/app.js +18 -27
- package/dist/core/app.js.map +1 -1
- package/dist/core/context.d.ts +90 -57
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +32 -33
- package/dist/core/context.js.map +1 -1
- package/dist/core/gcPressure.d.ts.map +1 -1
- package/dist/core/gcPressure.js +3 -4
- package/dist/core/gcPressure.js.map +1 -1
- package/dist/core/index.d.ts +6 -7
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +10 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/serverManifest.d.ts +1 -3
- package/dist/core/serverManifest.d.ts.map +1 -1
- package/dist/core/serverManifest.js +9 -4
- package/dist/core/serverManifest.js.map +1 -1
- package/dist/core/worker.d.ts.map +1 -1
- package/dist/core/worker.js +32 -35
- package/dist/core/worker.js.map +1 -1
- package/dist/logs/combined.log +10 -22
- package/dist/logs/error.log +6 -18
- package/dist/mcp-server/inputRequired.d.ts +52 -0
- package/dist/mcp-server/inputRequired.d.ts.map +1 -0
- package/dist/mcp-server/inputRequired.js +76 -0
- package/dist/mcp-server/inputRequired.js.map +1 -0
- package/dist/mcp-server/notifications.d.ts +33 -31
- package/dist/mcp-server/notifications.d.ts.map +1 -1
- package/dist/mcp-server/notifications.js +34 -26
- package/dist/mcp-server/notifications.js.map +1 -1
- package/dist/mcp-server/prompts/prompt-registration.d.ts +2 -2
- package/dist/mcp-server/prompts/prompt-registration.d.ts.map +1 -1
- package/dist/mcp-server/prompts/prompt-registration.js +15 -5
- package/dist/mcp-server/prompts/prompt-registration.js.map +1 -1
- package/dist/mcp-server/prompts/utils/promptDefinition.d.ts +1 -1
- package/dist/mcp-server/prompts/utils/promptDefinition.d.ts.map +1 -1
- package/dist/mcp-server/resources/resource-registration.d.ts +3 -3
- package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -1
- package/dist/mcp-server/resources/resource-registration.js +8 -15
- package/dist/mcp-server/resources/resource-registration.js.map +1 -1
- package/dist/mcp-server/resources/resourceSubscriptions.d.ts +45 -0
- package/dist/mcp-server/resources/resourceSubscriptions.d.ts.map +1 -0
- package/dist/mcp-server/resources/resourceSubscriptions.js +51 -0
- package/dist/mcp-server/resources/resourceSubscriptions.js.map +1 -0
- package/dist/mcp-server/resources/utils/resourceDefinition.d.ts +3 -5
- package/dist/mcp-server/resources/utils/resourceDefinition.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceDefinition.js +1 -1
- package/dist/mcp-server/resources/utils/resourceDefinition.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts +8 -15
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +21 -22
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
- package/dist/mcp-server/server.d.ts +12 -21
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +38 -28
- package/dist/mcp-server/server.js.map +1 -1
- package/dist/mcp-server/tools/tool-registration.d.ts +11 -33
- package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/tool-registration.js +17 -243
- package/dist/mcp-server/tools/tool-registration.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts +1 -3
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolDefinition.js +48 -1
- package/dist/mcp-server/tools/utils/toolDefinition.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +46 -20
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js +131 -25
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
- package/dist/mcp-server/transports/ITransport.d.ts +2 -2
- package/dist/mcp-server/transports/ITransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/authFactory.js +1 -1
- package/dist/mcp-server/transports/auth/authFactory.js.map +1 -1
- package/dist/mcp-server/transports/auth/lib/authTypes.d.ts +1 -1
- package/dist/mcp-server/transports/auth/lib/authTypes.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/lib/authUtils.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/lib/authUtils.js +5 -13
- package/dist/mcp-server/transports/auth/lib/authUtils.js.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js +5 -11
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js +9 -22
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js.map +1 -1
- package/dist/mcp-server/transports/heartbeat.d.ts.map +1 -1
- package/dist/mcp-server/transports/heartbeat.js +4 -8
- package/dist/mcp-server/transports/heartbeat.js.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.js +6 -24
- package/dist/mcp-server/transports/http/httpErrorHandler.js.map +1 -1
- package/dist/mcp-server/transports/http/httpServer.d.ts +3 -3
- package/dist/mcp-server/transports/http/httpServer.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpServer.js +15 -32
- package/dist/mcp-server/transports/http/httpServer.js.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.d.ts +25 -8
- package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.js +156 -373
- package/dist/mcp-server/transports/http/httpTransport.js.map +1 -1
- package/dist/mcp-server/transports/http/landing-page/assets/styles.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/landing-page/assets/styles.js +0 -1
- package/dist/mcp-server/transports/http/landing-page/assets/styles.js.map +1 -1
- package/dist/mcp-server/transports/http/landing-page/handler.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/landing-page/handler.js +4 -8
- package/dist/mcp-server/transports/http/landing-page/handler.js.map +1 -1
- package/dist/mcp-server/transports/http/landing-page/sections/tools.js +0 -2
- package/dist/mcp-server/transports/http/landing-page/sections/tools.js.map +1 -1
- package/dist/mcp-server/transports/http/protectedResourceMetadata.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/protectedResourceMetadata.js +2 -6
- package/dist/mcp-server/transports/http/protectedResourceMetadata.js.map +1 -1
- package/dist/mcp-server/transports/http/robotsTxt.js +2 -2
- package/dist/mcp-server/transports/http/robotsTxt.js.map +1 -1
- package/dist/mcp-server/transports/http/serverCard.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/serverCard.js +2 -6
- package/dist/mcp-server/transports/http/serverCard.js.map +1 -1
- package/dist/mcp-server/transports/http/sessionStore.d.ts +46 -66
- package/dist/mcp-server/transports/http/sessionStore.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/sessionStore.js +140 -238
- package/dist/mcp-server/transports/http/sessionStore.js.map +1 -1
- package/dist/mcp-server/transports/manager.d.ts +12 -4
- package/dist/mcp-server/transports/manager.d.ts.map +1 -1
- package/dist/mcp-server/transports/manager.js +35 -33
- package/dist/mcp-server/transports/manager.js.map +1 -1
- package/dist/mcp-server/transports/stdio/stdioTransport.d.ts +24 -31
- package/dist/mcp-server/transports/stdio/stdioTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/stdio/stdioTransport.js +23 -38
- package/dist/mcp-server/transports/stdio/stdioTransport.js.map +1 -1
- package/dist/mcp-server/types.d.ts +25 -0
- package/dist/mcp-server/types.d.ts.map +1 -0
- package/dist/mcp-server/types.js +10 -0
- package/dist/mcp-server/types.js.map +1 -0
- package/dist/services/canvas/core/CanvasInstance.d.ts +2 -2
- package/dist/services/canvas/core/CanvasInstance.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasInstance.js.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.d.ts +4 -4
- package/dist/services/canvas/core/CanvasRegistry.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.js +8 -18
- package/dist/services/canvas/core/CanvasRegistry.js.map +1 -1
- package/dist/services/canvas/core/DataCanvas.d.ts +5 -5
- package/dist/services/canvas/core/DataCanvas.d.ts.map +1 -1
- package/dist/services/canvas/core/DataCanvas.js +2 -3
- package/dist/services/canvas/core/DataCanvas.js.map +1 -1
- package/dist/services/canvas/core/IDataCanvasProvider.d.ts +11 -11
- package/dist/services/canvas/core/IDataCanvasProvider.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts +11 -11
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js +4 -10
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js.map +1 -1
- package/dist/services/llm/providers/openrouter.provider.d.ts.map +1 -1
- package/dist/services/llm/providers/openrouter.provider.js +2 -5
- package/dist/services/llm/providers/openrouter.provider.js.map +1 -1
- package/dist/services/mirror/core/defineMirror.js +1 -1
- package/dist/services/mirror/core/defineMirror.js.map +1 -1
- package/dist/services/mirror/types.d.ts +5 -5
- package/dist/services/mirror/types.d.ts.map +1 -1
- package/dist/services/speech/providers/elevenlabs.provider.js +1 -1
- package/dist/services/speech/providers/elevenlabs.provider.js.map +1 -1
- package/dist/services/speech/providers/whisper.provider.js +1 -1
- package/dist/services/speech/providers/whisper.provider.js.map +1 -1
- package/dist/storage/core/StorageService.d.ts +1 -1
- package/dist/storage/core/StorageService.d.ts.map +1 -1
- package/dist/storage/core/StorageService.js +12 -20
- package/dist/storage/core/StorageService.js.map +1 -1
- package/dist/storage/core/storageFactory.d.ts.map +1 -1
- package/dist/storage/core/storageFactory.js.map +1 -1
- package/dist/storage/core/storageValidation.d.ts +1 -1
- package/dist/storage/core/storageValidation.d.ts.map +1 -1
- package/dist/storage/core/storageValidation.js +2 -2
- package/dist/storage/core/storageValidation.js.map +1 -1
- package/dist/storage/providers/cloudflare/d1Provider.d.ts +1 -1
- package/dist/storage/providers/cloudflare/d1Provider.d.ts.map +1 -1
- package/dist/storage/providers/cloudflare/d1Provider.js +4 -12
- package/dist/storage/providers/cloudflare/d1Provider.js.map +1 -1
- package/dist/storage/providers/cloudflare/kvProvider.d.ts +1 -1
- package/dist/storage/providers/cloudflare/kvProvider.d.ts.map +1 -1
- package/dist/storage/providers/cloudflare/kvProvider.js +3 -8
- package/dist/storage/providers/cloudflare/kvProvider.js.map +1 -1
- package/dist/storage/providers/cloudflare/r2Provider.d.ts +1 -1
- package/dist/storage/providers/cloudflare/r2Provider.d.ts.map +1 -1
- package/dist/storage/providers/cloudflare/r2Provider.js +3 -8
- package/dist/storage/providers/cloudflare/r2Provider.js.map +1 -1
- package/dist/storage/providers/inMemory/inMemoryProvider.d.ts +1 -1
- package/dist/storage/providers/inMemory/inMemoryProvider.d.ts.map +1 -1
- package/dist/storage/providers/inMemory/inMemoryProvider.js +2 -4
- package/dist/storage/providers/inMemory/inMemoryProvider.js.map +1 -1
- package/dist/testing/index.d.ts +35 -12
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +53 -38
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/vitest.d.ts +1 -1
- package/dist/testing/vitest.d.ts.map +1 -1
- package/dist/types-global/errors.d.ts +28 -15
- package/dist/types-global/errors.d.ts.map +1 -1
- package/dist/types-global/errors.js +8 -1
- package/dist/types-global/errors.js.map +1 -1
- package/dist/utils/formatting/diffFormatter.d.ts +5 -5
- package/dist/utils/formatting/diffFormatter.d.ts.map +1 -1
- package/dist/utils/formatting/diffFormatter.js +7 -20
- package/dist/utils/formatting/diffFormatter.js.map +1 -1
- package/dist/utils/formatting/tableFormatter.d.ts +3 -3
- package/dist/utils/formatting/tableFormatter.d.ts.map +1 -1
- package/dist/utils/formatting/tableFormatter.js +6 -17
- package/dist/utils/formatting/tableFormatter.js.map +1 -1
- package/dist/utils/formatting/treeFormatter.d.ts +3 -3
- package/dist/utils/formatting/treeFormatter.d.ts.map +1 -1
- package/dist/utils/formatting/treeFormatter.js +5 -18
- package/dist/utils/formatting/treeFormatter.js.map +1 -1
- package/dist/utils/index.d.ts +4 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -2
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.d.ts +1 -1
- package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.js +23 -11
- package/dist/utils/internal/error-handler/errorHandler.js.map +1 -1
- package/dist/utils/internal/error-handler/types.d.ts +10 -13
- package/dist/utils/internal/error-handler/types.d.ts.map +1 -1
- package/dist/utils/internal/logger.d.ts +3 -3
- package/dist/utils/internal/logger.d.ts.map +1 -1
- package/dist/utils/internal/logger.js +11 -5
- package/dist/utils/internal/logger.js.map +1 -1
- package/dist/utils/internal/performance.d.ts +1 -1
- package/dist/utils/internal/performance.d.ts.map +1 -1
- package/dist/utils/internal/performance.js +57 -13
- package/dist/utils/internal/performance.js.map +1 -1
- package/dist/utils/internal/requestContext.d.ts +79 -55
- package/dist/utils/internal/requestContext.d.ts.map +1 -1
- package/dist/utils/internal/requestContext.js +77 -32
- package/dist/utils/internal/requestContext.js.map +1 -1
- package/dist/utils/metrics/tokenCounter.d.ts +3 -3
- package/dist/utils/metrics/tokenCounter.d.ts.map +1 -1
- package/dist/utils/metrics/tokenCounter.js.map +1 -1
- package/dist/utils/network/fetchWithTimeout.d.ts +2 -2
- package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -1
- package/dist/utils/network/fetchWithTimeout.js +8 -24
- package/dist/utils/network/fetchWithTimeout.js.map +1 -1
- package/dist/utils/network/retry.d.ts +2 -2
- package/dist/utils/network/retry.d.ts.map +1 -1
- package/dist/utils/overflow/outlineOnOverflow.d.ts +1 -1
- package/dist/utils/overflow/outlineOnOverflow.d.ts.map +1 -1
- package/dist/utils/pagination/pagination.d.ts +3 -3
- package/dist/utils/pagination/pagination.d.ts.map +1 -1
- package/dist/utils/pagination/pagination.js +3 -3
- package/dist/utils/pagination/pagination.js.map +1 -1
- package/dist/utils/parsing/csvParser.d.ts +2 -2
- package/dist/utils/parsing/csvParser.d.ts.map +1 -1
- package/dist/utils/parsing/csvParser.js +4 -8
- package/dist/utils/parsing/csvParser.js.map +1 -1
- package/dist/utils/parsing/dateParser.d.ts +3 -3
- package/dist/utils/parsing/dateParser.d.ts.map +1 -1
- package/dist/utils/parsing/dateParser.js +3 -2
- package/dist/utils/parsing/dateParser.js.map +1 -1
- package/dist/utils/parsing/frontmatterParser.d.ts +2 -2
- package/dist/utils/parsing/frontmatterParser.d.ts.map +1 -1
- package/dist/utils/parsing/frontmatterParser.js +7 -10
- package/dist/utils/parsing/frontmatterParser.js.map +1 -1
- package/dist/utils/parsing/htmlExtractor.d.ts +2 -2
- package/dist/utils/parsing/htmlExtractor.d.ts.map +1 -1
- package/dist/utils/parsing/htmlExtractor.js +6 -11
- package/dist/utils/parsing/htmlExtractor.js.map +1 -1
- package/dist/utils/parsing/jsonParser.d.ts +2 -2
- package/dist/utils/parsing/jsonParser.d.ts.map +1 -1
- package/dist/utils/parsing/jsonParser.js +4 -8
- package/dist/utils/parsing/jsonParser.js.map +1 -1
- package/dist/utils/parsing/pdfParser.d.ts +10 -10
- package/dist/utils/parsing/pdfParser.d.ts.map +1 -1
- package/dist/utils/parsing/pdfParser.js +26 -89
- package/dist/utils/parsing/pdfParser.js.map +1 -1
- package/dist/utils/parsing/xmlParser.d.ts +2 -2
- package/dist/utils/parsing/xmlParser.d.ts.map +1 -1
- package/dist/utils/parsing/xmlParser.js +4 -8
- package/dist/utils/parsing/xmlParser.js.map +1 -1
- package/dist/utils/parsing/yamlParser.d.ts +2 -2
- package/dist/utils/parsing/yamlParser.d.ts.map +1 -1
- package/dist/utils/parsing/yamlParser.js +4 -8
- package/dist/utils/parsing/yamlParser.js.map +1 -1
- package/dist/utils/scheduling/scheduler.d.ts.map +1 -1
- package/dist/utils/scheduling/scheduler.js +5 -6
- package/dist/utils/scheduling/scheduler.js.map +1 -1
- package/dist/utils/security/rateLimiter.d.ts +2 -2
- package/dist/utils/security/rateLimiter.d.ts.map +1 -1
- package/dist/utils/security/rateLimiter.js +1 -1
- package/dist/utils/security/rateLimiter.js.map +1 -1
- package/dist/utils/telemetry/attributes.d.ts +23 -7
- package/dist/utils/telemetry/attributes.d.ts.map +1 -1
- package/dist/utils/telemetry/attributes.js +23 -10
- package/dist/utils/telemetry/attributes.js.map +1 -1
- package/dist/utils/telemetry/trace.d.ts +3 -3
- package/dist/utils/telemetry/trace.d.ts.map +1 -1
- package/dist/utils/telemetry/trace.js +4 -2
- package/dist/utils/telemetry/trace.js.map +1 -1
- package/package.json +22 -26
- package/scripts/lint-mcp.ts +1 -3
- package/scripts/lint-packaging.ts +1 -1
- package/skills/add-service/SKILL.md +2 -2
- package/skills/add-test/SKILL.md +42 -20
- package/skills/add-tool/SKILL.md +68 -19
- package/skills/api-config/SKILL.md +1 -11
- package/skills/api-context/SKILL.md +175 -111
- package/skills/api-linter/SKILL.md +2 -2
- package/skills/api-telemetry/SKILL.md +8 -12
- package/skills/api-testing/SKILL.md +53 -52
- package/skills/code-simplifier/SKILL.md +2 -2
- package/skills/design-mcp-server/SKILL.md +31 -17
- package/skills/field-test/SKILL.md +4 -2
- package/skills/polish-docs-meta/SKILL.md +1 -1
- package/skills/polish-docs-meta/references/agent-protocol.md +2 -2
- package/skills/polish-docs-meta/references/readme.md +1 -1
- package/skills/release-and-publish/SKILL.md +3 -1
- package/skills/report-issue-framework/SKILL.md +2 -2
- package/skills/report-issue-local/SKILL.md +2 -2
- package/skills/security-pass/SKILL.md +16 -14
- package/templates/AGENTS.md +6 -6
- package/templates/CLAUDE.md +6 -6
- package/templates/tests/resources/echo.resource.test.ts +16 -9
- package/dist/mcp-server/elicitation.d.ts +0 -64
- package/dist/mcp-server/elicitation.d.ts.map +0 -1
- package/dist/mcp-server/elicitation.js +0 -81
- package/dist/mcp-server/elicitation.js.map +0 -1
- package/dist/mcp-server/protocolSession.d.ts +0 -34
- package/dist/mcp-server/protocolSession.d.ts.map +0 -1
- package/dist/mcp-server/protocolSession.js +0 -13
- package/dist/mcp-server/protocolSession.js.map +0 -1
- package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.d.ts +0 -53
- package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.d.ts.map +0 -1
- package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.js +0 -65
- package/dist/mcp-server/tasks/core/evictingTaskMessageQueue.js.map +0 -1
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.d.ts +0 -70
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.d.ts.map +0 -1
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.js +0 -130
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.js.map +0 -1
- package/dist/mcp-server/tasks/core/storageBackedTaskStore.d.ts +0 -109
- package/dist/mcp-server/tasks/core/storageBackedTaskStore.d.ts.map +0 -1
- package/dist/mcp-server/tasks/core/storageBackedTaskStore.js +0 -209
- package/dist/mcp-server/tasks/core/storageBackedTaskStore.js.map +0 -1
- package/dist/mcp-server/tasks/core/taskManager.d.ts +0 -91
- package/dist/mcp-server/tasks/core/taskManager.d.ts.map +0 -1
- package/dist/mcp-server/tasks/core/taskManager.js +0 -210
- package/dist/mcp-server/tasks/core/taskManager.js.map +0 -1
- package/dist/mcp-server/tasks/core/taskTypes.d.ts +0 -18
- package/dist/mcp-server/tasks/core/taskTypes.d.ts.map +0 -1
- package/dist/mcp-server/tasks/core/taskTypes.js +0 -20
- package/dist/mcp-server/tasks/core/taskTypes.js.map +0 -1
- package/dist/mcp-server/tasks/utils/taskToolDefinition.d.ts +0 -101
- package/dist/mcp-server/tasks/utils/taskToolDefinition.d.ts.map +0 -1
- package/dist/mcp-server/tasks/utils/taskToolDefinition.js +0 -14
- package/dist/mcp-server/tasks/utils/taskToolDefinition.js.map +0 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: api-context
|
|
3
3
|
description: >
|
|
4
|
-
Canonical reference for the unified `Context` object passed to every tool and resource handler in `@cyanheads/mcp-ts-core`. Covers the full interface, all sub-APIs (`ctx.log`, `ctx.state`, `ctx.
|
|
4
|
+
Canonical reference for the unified `Context` object passed to every tool and resource handler in `@cyanheads/mcp-ts-core`. Covers the full interface, its `RequestContext` base, all sub-APIs (`ctx.log`, `ctx.state`, `ctx.requestInput`, `ctx.inputs`, `ctx.enrich`, `ctx.content`), and when to use each.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "
|
|
7
|
+
version: "2.0"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
## Overview
|
|
13
13
|
|
|
14
|
-
Every tool and resource handler receives a single `Context` (`ctx`) argument. It provides request identity, structured logging, tenant-scoped storage,
|
|
14
|
+
Every tool and resource handler receives a single `Context` (`ctx`) argument. It provides request identity, structured logging, tenant-scoped storage, multi-round-trip input collection, and cancellation — all auto-correlated to the current request.
|
|
15
15
|
|
|
16
16
|
The framework auto-instruments every handler call (OTel span, duration, payload metrics). Use `ctx.log` for domain-specific logging and `ctx.state` for storage inside handlers. Use the global `logger` and `StorageService` directly only in lifecycle/background code (`setup()`, services).
|
|
17
17
|
|
|
@@ -22,8 +22,8 @@ The framework auto-instruments every handler call (OTel span, duration, payload
|
|
|
22
22
|
```ts
|
|
23
23
|
import type { Context } from '@cyanheads/mcp-ts-core';
|
|
24
24
|
|
|
25
|
-
interface Context {
|
|
26
|
-
// Identity & tracing
|
|
25
|
+
interface Context extends RequestContext {
|
|
26
|
+
// Identity & tracing (inherited from RequestContext — see § RequestContext)
|
|
27
27
|
readonly requestId: string; // Unique per request, auto-generated
|
|
28
28
|
readonly timestamp: string; // ISO 8601 request start time
|
|
29
29
|
readonly tenantId?: string; // JWT 'tid' claim; 'default' for stdio and HTTP+MCP_AUTH_MODE=none
|
|
@@ -31,15 +31,19 @@ interface Context {
|
|
|
31
31
|
readonly traceId?: string; // OTEL trace ID (present when OTEL enabled)
|
|
32
32
|
readonly spanId?: string; // OTEL span ID (present when OTEL enabled)
|
|
33
33
|
readonly auth?: AuthContext; // Parsed auth claims (clientId, scopes, sub)
|
|
34
|
+
readonly operation?: string; // Label for the operation this context belongs to
|
|
35
|
+
readonly extra?: Readonly<Record<string, unknown>>; // Correlation bag — the one open field
|
|
34
36
|
|
|
35
|
-
// Structured logging — auto-includes requestId, traceId, tenantId
|
|
37
|
+
// Structured logging — auto-includes requestId, traceId, tenantId.
|
|
38
|
+
// Dual-sink: Pino on the server, plus notifications/message to the client.
|
|
36
39
|
readonly log: ContextLogger;
|
|
37
40
|
|
|
38
41
|
// Tenant-scoped key-value storage
|
|
39
42
|
readonly state: ContextState;
|
|
40
43
|
|
|
41
|
-
//
|
|
42
|
-
readonly
|
|
44
|
+
// Multi-round-trip input — always present, both eras (see § ctx.requestInput)
|
|
45
|
+
readonly requestInput: RequestInputFn; // (spec) => never — suspends and asks the caller
|
|
46
|
+
readonly inputs: ContextInputs; // reader over a retried request's responses
|
|
43
47
|
|
|
44
48
|
// List-changed / resource-updated notifications — wired in every handler ctx;
|
|
45
49
|
// delivery is request-scoped (see § list-changed notifications)
|
|
@@ -51,9 +55,6 @@ interface Context {
|
|
|
51
55
|
// Cancellation
|
|
52
56
|
readonly signal: AbortSignal;
|
|
53
57
|
|
|
54
|
-
// Task progress — present only when tool is defined with task: true
|
|
55
|
-
readonly progress?: ContextProgress;
|
|
56
|
-
|
|
57
58
|
// Raw URI — present only for resource handlers
|
|
58
59
|
readonly uri?: URL;
|
|
59
60
|
|
|
@@ -91,10 +92,65 @@ interface Context {
|
|
|
91
92
|
|
|
92
93
|
---
|
|
93
94
|
|
|
95
|
+
## `RequestContext` — the one canonical request shape
|
|
96
|
+
|
|
97
|
+
`Context extends RequestContext`. There is a single request-shape type; the handler-facing `Context` adds handler-only surfaces (`log`, `state`, `signal`, `requestInput`, `inputs`, `enrich`, `content`, `uri`) on top of it and redeclares none of the identity fields. A handler's `ctx` is therefore assignable anywhere a `RequestContext` is — services, storage, the framework logger — with no slice helper and no cast.
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import { requestContextService, withExtra } from '@cyanheads/mcp-ts-core/utils';
|
|
101
|
+
import type { RequestContext } from '@cyanheads/mcp-ts-core/utils';
|
|
102
|
+
|
|
103
|
+
// A service typed against RequestContext accepts a handler ctx directly.
|
|
104
|
+
async function fetchUser(id: string, ctx: RequestContext) { /* … */ }
|
|
105
|
+
await fetchUser('123', ctx); // ctx is a Context — no conversion
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Closed by design
|
|
109
|
+
|
|
110
|
+
`RequestContext` has **no index signature**. Its fields are exactly: `auth`, `extra`, `operation`, `requestId`, `sessionId`, `spanId`, `tenantId`, `timestamp`, `traceId`. A misspelled canonical field (`tenatId`) is a compile error instead of a silently-ignored key.
|
|
111
|
+
|
|
112
|
+
Operation-specific correlation data goes in **`extra`** — the one deliberate open bag (`Readonly<Record<string, unknown>>`). The logger flattens `extra` into the emitted line, so log output looks the same as a top-level spread.
|
|
113
|
+
|
|
114
|
+
### Adding correlation data
|
|
115
|
+
|
|
116
|
+
Three supported ways, most common first:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
// 1. Per-log-call metadata — the common case. Nothing lands on the context.
|
|
120
|
+
ctx.log.info('Retrying upstream call', { attempt, url });
|
|
121
|
+
|
|
122
|
+
// 2. A copy of this context carrying extra fields. `withExtra` MERGES into any
|
|
123
|
+
// bag the parent already had; a hand-written `{ ...ctx, extra: {…} }` replaces it.
|
|
124
|
+
logger.warning('Retrying upstream call', withExtra(ctx, { attempt, url }));
|
|
125
|
+
|
|
126
|
+
// 3. A derived context for a sub-operation. `additionalContext` lands on `extra`,
|
|
127
|
+
// merged over whatever the parent already carried.
|
|
128
|
+
const childCtx = requestContextService.createRequestContext({
|
|
129
|
+
parentContext: ctx,
|
|
130
|
+
operation: 'processItem',
|
|
131
|
+
additionalContext: { itemId: item.id }, // → childCtx.extra.itemId
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Reading an ad-hoc key back off a context:
|
|
135
|
+
const itemId = childCtx.extra?.itemId;
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`createRequestContext(params)` takes a closed parameter object — `additionalContext`, `operation`, `parentContext`, `tenantId` — and nothing else; a key it doesn't declare is a compile error rather than an arbitrary passthrough.
|
|
139
|
+
|
|
140
|
+
Never re-open the shape to get past a type error: no index signature, no widening a parameter back to `Record<string, unknown>`, no `as` cast. A `{ ...ctx, someKey }` object literal that fails to compile is the signal to move `someKey` into `extra`, not to loosen the type.
|
|
141
|
+
|
|
142
|
+
`ErrorContext` (the `ErrorHandler` call's `context`) is `Partial<RequestContext>` and is closed the same way — put ad-hoc keys under `extra` via `withExtra`, or pass them in the `ErrorHandler` call's own `context` field.
|
|
143
|
+
|
|
144
|
+
`RequestContextLike` is a deprecated alias for `RequestContext`, kept for one minor. Replace every use with `RequestContext`, and collapse any `RequestContextLike | RequestContext` parameter union to plain `RequestContext`.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
94
148
|
## `ctx.log`
|
|
95
149
|
|
|
96
150
|
Request-scoped structured logger. Every log line is automatically annotated with `requestId`, `traceId`, and `tenantId` — no manual spreading needed.
|
|
97
151
|
|
|
152
|
+
**Dual-sink.** Each call writes to Pino *and* mirrors onto the MCP wire as a `notifications/message` (the framework advertises the `logging` capability, and the SDK filters by the level the client set via `logging/setLevel`). The wire payload is `{ message, ...data }`; `ctx.log.error` adds `error: <message>`. Delivery is fire-and-forget — a client that never upgraded to SSE, set a higher level, or already disconnected drops the notification, and a failed send never fails the handler. Treat `ctx.log` as client-visible: it is no longer a server-only sink, so don't log anything there you wouldn't put in a tool result.
|
|
153
|
+
|
|
98
154
|
### Methods
|
|
99
155
|
|
|
100
156
|
| Method | Level |
|
|
@@ -255,71 +311,120 @@ await ctx.state.set(sessionKey, value);
|
|
|
255
311
|
### Behavior notes
|
|
256
312
|
|
|
257
313
|
- **Not a tenant boundary.** `ctx.state` is still tenant-scoped. Building session-scoped state is the consumer's responsibility — prefix with `session/${ctx.sessionId}/` as shown above.
|
|
258
|
-
- **
|
|
314
|
+
- **Protocol revision.** Sessions belong to the 2025-era arm, which negotiates its revision through `initialize` and carries `Mcp-Session-Id`. The [2026-07-28 revision](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports) has no session at all — it is per-request, selected by the request's own `_meta` envelope — so `ctx.sessionId` is `undefined` for every request served on that leg.
|
|
259
315
|
- **Worker bundle.** Workers use the same HTTP transport plumbing; session behavior matches Node HTTP.
|
|
260
316
|
|
|
261
317
|
---
|
|
262
318
|
|
|
263
|
-
## `ctx.
|
|
319
|
+
## `ctx.requestInput` / `ctx.inputs`
|
|
320
|
+
|
|
321
|
+
Always present, on every transport and both protocol eras. A handler that needs something the caller didn't supply **returns** `ctx.requestInput(...)` and is re-entered with the answers on `ctx.inputs` — there is no mid-handler `await` for user input.
|
|
264
322
|
|
|
265
|
-
|
|
323
|
+
`ctx.requestInput(spec)` never returns: it throws an `InputRequiredSignal` that the tool, resource, and prompt handler factories catch and convert into the protocol's [`input_required`](https://modelcontextprotocol.io/specification/2026-07-28/basic/patterns/mrtr) result. It bypasses the error classifier entirely — no span, no log, no `isError`.
|
|
266
324
|
|
|
267
|
-
|
|
325
|
+
One code path serves both eras. A 2026-07-28 client fulfils the embedded requests and retries the call; for a 2025-era session the SDK's legacy shim fulfils the same returns by issuing real `elicitation/create` / `sampling/createMessage` / `roots/list` round trips and re-entering the handler itself.
|
|
268
326
|
|
|
269
|
-
###
|
|
327
|
+
### The shape of a multi-round-trip handler
|
|
270
328
|
|
|
271
|
-
|
|
329
|
+
Read `ctx.inputs` first, request only what is still missing, and write the call in return position so TypeScript narrows the line below it.
|
|
272
330
|
|
|
273
331
|
```ts
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
332
|
+
import { inputRequired, tool, z } from '@cyanheads/mcp-ts-core';
|
|
333
|
+
import { validationError } from '@cyanheads/mcp-ts-core/errors';
|
|
334
|
+
|
|
335
|
+
const Confirm = z.object({
|
|
336
|
+
confirm: z.boolean().describe('Whether to proceed with the deletion.'),
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
export const deletePath = tool('delete_path', {
|
|
340
|
+
description: 'Delete a path after confirming with the user.',
|
|
341
|
+
input: z.object({ path: z.string().describe('Path to delete') }),
|
|
342
|
+
output: z.object({ deleted: z.string().describe('The path that was deleted') }),
|
|
343
|
+
annotations: { destructiveHint: true },
|
|
344
|
+
|
|
345
|
+
handler(input, ctx) {
|
|
346
|
+
// A declined or cancelled prompt is a dead end, not a round to retry —
|
|
347
|
+
// re-asking loops until the round budget runs out.
|
|
348
|
+
const view = ctx.inputs.view('confirm');
|
|
349
|
+
if (view.kind === 'elicit' && view.action !== 'accept') {
|
|
350
|
+
throw validationError(`User ${view.action} the confirmation.`);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const answer = ctx.inputs.accepted('confirm', Confirm);
|
|
354
|
+
if (!answer) {
|
|
355
|
+
return ctx.requestInput({
|
|
356
|
+
inputRequests: {
|
|
357
|
+
confirm: inputRequired.elicit({
|
|
358
|
+
message: `Delete ${input.path}?`,
|
|
359
|
+
requestedSchema: Confirm,
|
|
360
|
+
}),
|
|
361
|
+
},
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
// `answer` is narrowed here.
|
|
365
|
+
if (!answer.confirm) throw validationError('Deletion not confirmed.');
|
|
366
|
+
|
|
367
|
+
return { deleted: remove(input.path) };
|
|
368
|
+
},
|
|
369
|
+
});
|
|
291
370
|
```
|
|
292
371
|
|
|
293
|
-
`
|
|
372
|
+
`ctx.requestInput` returns `never`, so `return ctx.requestInput(...)` type-checks against any output type. Calling it as a bare statement works at runtime — and is the only option from a service-layer helper — but TypeScript will not narrow across it.
|
|
373
|
+
|
|
374
|
+
### Building the embedded requests
|
|
375
|
+
|
|
376
|
+
`inputRequired` is re-exported from the main entry. Its per-kind constructors build the entries of `inputRequests`:
|
|
377
|
+
|
|
378
|
+
| Constructor | Wire request | Notes |
|
|
379
|
+
|:---|:---|:---|
|
|
380
|
+
| `inputRequired.elicit({ message, requestedSchema })` | `elicitation/create` (form) | `requestedSchema` accepts a Zod schema; shapes the restricted elicitation JSON Schema can't express throw a `TypeError` before anything is sent |
|
|
381
|
+
| `inputRequired.elicitUrl({ message, url })` | `elicitation/create` (URL) | Authorization flows, hosted forms. On 2026-07-28 URL mode rides the same multi-round-trip flow; the 2025-era `elicitationId` is not part of that shape — correlate with your own identifier inside `requestState` |
|
|
382
|
+
| `inputRequired.createMessage(params)` | `sampling/createMessage` | Ask the client's model |
|
|
383
|
+
| `inputRequired.listRoots()` | `roots/list` | Ask for the client's filesystem roots |
|
|
384
|
+
|
|
385
|
+
At least one of `inputRequests` or `requestState` must be supplied — the builder throws a `TypeError` otherwise.
|
|
386
|
+
|
|
387
|
+
### `requestState` — carrying server state across rounds
|
|
294
388
|
|
|
295
389
|
```ts
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
390
|
+
return ctx.requestInput({
|
|
391
|
+
inputRequests: { confirm: inputRequired.elicit({ message, requestedSchema: Confirm }) },
|
|
392
|
+
requestState: JSON.stringify({ jobId }),
|
|
393
|
+
});
|
|
394
|
+
// Next round:
|
|
395
|
+
const state = ctx.inputs.state<string>();
|
|
302
396
|
```
|
|
303
397
|
|
|
304
|
-
|
|
398
|
+
`requestState` round-trips **through the client** and comes back as attacker-controlled input. Integrity-protect (HMAC/AEAD) anything that influences authorization, resource access, or business logic, and reject state that fails verification — the SDK does not do this for you.
|
|
399
|
+
|
|
400
|
+
### `ctx.inputs` — reading a retried request's responses
|
|
401
|
+
|
|
402
|
+
Empty on the first round; populated on re-entry.
|
|
403
|
+
|
|
404
|
+
| Member | Returns |
|
|
405
|
+
|:---|:---|
|
|
406
|
+
| `accepted(key, schema?)` | The accepted form-mode content for `key`, or `undefined` when the key is missing, the user declined or cancelled, the response was another kind, or (with a schema) validation failed |
|
|
407
|
+
| `view(key)` | Discriminated view of one entry: `{ kind: 'missing' }` \| `{ kind: 'elicit', action, content? }` \| `{ kind: 'sampling', result }` \| `{ kind: 'roots', roots }` |
|
|
408
|
+
| `state<T>()` | This round's `requestState` — verified value, raw wire string when no verifier is configured, or `undefined` on the first round |
|
|
409
|
+
| `dropped` | Keys the SDK dropped because the client sent a wrapped rather than a bare response object. Re-issue those requests instead of hard-failing |
|
|
410
|
+
| `responses` | The raw response map, for kinds the helpers don't cover |
|
|
411
|
+
|
|
412
|
+
Two rules follow from what the SDK does *not* do:
|
|
413
|
+
|
|
414
|
+
- **Responses are never re-validated against the schema the request advertised.** Pass the schema to `accepted(key, schema)` wherever the content matters, and treat every value as untrusted client input.
|
|
415
|
+
- **`undefined` from `accepted()` collapses five different outcomes into one.** Missing, declined, cancelled, wrong response kind, and schema-invalid are indistinguishable through it. Branch on `view(key)` when decline/cancel needs different handling from "not asked yet" — as above, re-issuing a request the user already declined just burns rounds.
|
|
305
416
|
|
|
306
|
-
###
|
|
417
|
+
### Testing
|
|
307
418
|
|
|
308
|
-
|
|
419
|
+
`createMockContext({ inputResponses, requestState })` seeds `ctx.inputs`, so a handler can be driven straight into its second round:
|
|
309
420
|
|
|
310
421
|
```ts
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
'https://example.com/oauth/authorize?state=...',
|
|
315
|
-
);
|
|
316
|
-
if (result.action !== 'accept') throw forbidden('Authorization declined');
|
|
317
|
-
}
|
|
422
|
+
const ctx = createMockContext({
|
|
423
|
+
inputResponses: { confirm: { action: 'accept', content: { confirm: true } } },
|
|
424
|
+
});
|
|
318
425
|
```
|
|
319
426
|
|
|
320
|
-
`
|
|
321
|
-
|
|
322
|
-
**Convention:** Only call `ctx.elicit` from tool handlers, not from services.
|
|
427
|
+
**Convention:** only call `ctx.requestInput` from tool, resource, and prompt handlers — not from services.
|
|
323
428
|
|
|
324
429
|
---
|
|
325
430
|
|
|
@@ -342,15 +447,21 @@ A notification fired **from inside a handler** routes through that request's own
|
|
|
342
447
|
| Fired from | stdio | HTTP / Workers |
|
|
343
448
|
|:-----------|:------|:---------------|
|
|
344
449
|
| A tool / resource handler | ✅ delivered | ✅ delivered (on the request's SSE response stream) |
|
|
345
|
-
| A `
|
|
450
|
+
| A `setup()` hook, cron job, or any non-request scope | ✅ delivered | ⚠️ dropped — no request scope to route through |
|
|
451
|
+
|
|
452
|
+
The background-under-HTTP gap is a known limitation; a session-scoped notification bus would close it.
|
|
453
|
+
|
|
454
|
+
### `notifyResourceUpdated` is subscription-scoped
|
|
346
455
|
|
|
347
|
-
The
|
|
456
|
+
The framework advertises `resources: { subscribe: true }` and backs it with real `resources/subscribe` / `resources/unsubscribe` handlers, so `notifyResourceUpdated(uri)` emits only for URIs the connected client actually subscribed to; an unsubscribed URI logs at debug and sends nothing. Both handlers are idempotent — re-subscribing is a no-op, and unsubscribing from a URI that was never subscribed succeeds.
|
|
457
|
+
|
|
458
|
+
The registry's scope is the `McpServer` instance, which is also the connection: one persistent instance per session on the 2025-era sessionful arm, one per request under per-request serving. On the per-request leg a subscription cannot outlive the request that created it, so a handler-time `ctx.notifyResourceUpdated(uri)` delivers only when that same exchange subscribed first.
|
|
348
459
|
|
|
349
460
|
---
|
|
350
461
|
|
|
351
462
|
## `ctx.signal`
|
|
352
463
|
|
|
353
|
-
Standard `AbortSignal`. Present on every context.
|
|
464
|
+
Standard `AbortSignal`. Present on every context. Fires when the client cancels the request — and when the transport closes, which aborts every in-flight handler.
|
|
354
465
|
|
|
355
466
|
```ts
|
|
356
467
|
// Check before expensive operations
|
|
@@ -366,55 +477,6 @@ for (const item of items) {
|
|
|
366
477
|
}
|
|
367
478
|
```
|
|
368
479
|
|
|
369
|
-
In task tools (`task: true`), the framework signals `ctx.signal` when the client sends a cancellation request.
|
|
370
|
-
|
|
371
|
-
---
|
|
372
|
-
|
|
373
|
-
## `ctx.progress`
|
|
374
|
-
|
|
375
|
-
Present only when the tool definition includes `task: true`. Undefined for standard (non-task) tools and all resource handlers.
|
|
376
|
-
|
|
377
|
-
### Methods
|
|
378
|
-
|
|
379
|
-
| Method | Purpose |
|
|
380
|
-
|:-------|:--------|
|
|
381
|
-
| `ctx.progress.setTotal(n)` | Set the total number of steps (enables percentage calculation on client) |
|
|
382
|
-
| `ctx.progress.increment(amount?)` | Advance progress by `amount` (default: 1) |
|
|
383
|
-
| `ctx.progress.update(message)` | Send a descriptive status message without advancing the counter |
|
|
384
|
-
|
|
385
|
-
### Usage
|
|
386
|
-
|
|
387
|
-
```ts
|
|
388
|
-
const asyncCountdown = tool('async_countdown', {
|
|
389
|
-
description: 'Count down from a number with progress updates.',
|
|
390
|
-
task: true,
|
|
391
|
-
input: z.object({
|
|
392
|
-
count: z.number().int().positive().describe('Number to count down from'),
|
|
393
|
-
delayMs: z.number().default(1000).describe('Delay between counts in ms'),
|
|
394
|
-
}),
|
|
395
|
-
output: z.object({
|
|
396
|
-
finalCount: z.number().describe('Final count value'),
|
|
397
|
-
message: z.string().describe('Completion message'),
|
|
398
|
-
}),
|
|
399
|
-
|
|
400
|
-
async handler(input, ctx) {
|
|
401
|
-
await ctx.progress!.setTotal(input.count);
|
|
402
|
-
|
|
403
|
-
for (let i = input.count; i > 0; i--) {
|
|
404
|
-
if (ctx.signal.aborted) break;
|
|
405
|
-
|
|
406
|
-
await ctx.progress!.update(`Counting: ${i}`);
|
|
407
|
-
await new Promise(resolve => setTimeout(resolve, input.delayMs));
|
|
408
|
-
await ctx.progress!.increment();
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
return { finalCount: 0, message: 'Countdown complete' };
|
|
412
|
-
},
|
|
413
|
-
});
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
**Note:** Use the non-null assertion (`ctx.progress!`) when accessing inside a `task: true` handler — the type is `ContextProgress | undefined` even though it's guaranteed present at runtime. TypeScript cannot narrow based on the `task` flag.
|
|
417
|
-
|
|
418
480
|
---
|
|
419
481
|
|
|
420
482
|
## `ctx.uri`
|
|
@@ -548,7 +610,7 @@ The `≥5 words` lint rule on contract `recovery` (validated at lint time) makes
|
|
|
548
610
|
|
|
549
611
|
## `ctx.enrich`
|
|
550
612
|
|
|
551
|
-
Always present on `Context`. Accumulates agent-facing **success-path** context — empty-result notices, the query/filter as the server parsed it, pagination totals — onto the request. The framework merges it into `structuredContent`,
|
|
613
|
+
Always present on `Context`. Accumulates agent-facing **success-path** context — empty-result notices, the query/filter as the server parsed it, pagination totals — onto the request. The framework merges it into `structuredContent`, folds the `enrichment` block into the tool's advertised `outputSchema`, and mirrors it into a `content[]` trailer. The success-path counterpart to `ctx.fail` / `ctx.recoveryFor`.
|
|
552
614
|
|
|
553
615
|
```ts
|
|
554
616
|
export const search = tool('search', {
|
|
@@ -698,21 +760,23 @@ Test content blocks with `getContentBlocks(ctx)` from `@cyanheads/mcp-ts-core/te
|
|
|
698
760
|
| `ctx.requestId` | `string` | Always |
|
|
699
761
|
| `ctx.timestamp` | `string` | Always |
|
|
700
762
|
| `ctx.tenantId` | `string \| undefined` | Stdio (`'default'`); HTTP+`MCP_AUTH_MODE=none` (`'default'`); HTTP+`jwt`/`oauth` (JWT `tid` claim — undefined if absent) |
|
|
701
|
-
| `ctx.sessionId` | `string \| undefined` | HTTP `stateful` / `auto` mode; stateless HTTP only when `createApp({ context: { exposeStatelessSessionId: true } })`; never in stdio or
|
|
763
|
+
| `ctx.sessionId` | `string \| undefined` | HTTP `stateful` / `auto` mode; stateless HTTP only when `createApp({ context: { exposeStatelessSessionId: true } })`; never in stdio or on the session-less 2026-07-28 leg |
|
|
702
764
|
| `ctx.traceId` | `string \| undefined` | OTEL enabled |
|
|
703
765
|
| `ctx.spanId` | `string \| undefined` | OTEL enabled |
|
|
704
766
|
| `ctx.auth` | `AuthContext \| undefined` | Auth enabled |
|
|
767
|
+
| `ctx.operation` | `string \| undefined` | Set by the context that created it (`'HandleToolRequest'` for tool calls) |
|
|
768
|
+
| `ctx.extra` | `Readonly<Record<string, unknown>> \| undefined` | When correlation data was attached — the one open bag on the closed shape |
|
|
705
769
|
| `ctx.log` | `ContextLogger` | Always |
|
|
706
770
|
| `ctx.state` | `ContextState` | Always (throws if `tenantId` missing) |
|
|
707
771
|
| `ctx.signal` | `AbortSignal` | Always |
|
|
708
772
|
| `ctx.enrich` | `Enrich` | Always; typed on `HandlerContext<R, E>` when an `enrichment` block is declared |
|
|
709
773
|
| `ctx.content` | `ContentCollect` | Always — prepends image/audio blocks to `content[]`, never `structuredContent` |
|
|
710
|
-
| `ctx.
|
|
774
|
+
| `ctx.requestInput` | `(spec) => never` | Always — suspends the handler and asks the caller for more input |
|
|
775
|
+
| `ctx.inputs` | `ContextInputs` | Always; empty until the request is retried with responses |
|
|
711
776
|
| `ctx.notifyResourceListChanged` | `function \| undefined` | Always in handler ctx; delivery request-scoped (see [§ list-changed notifications](#list-changed-notifications-ctxnotify)) |
|
|
712
|
-
| `ctx.notifyResourceUpdated` | `function \| undefined` | Always in handler ctx; delivery request-scoped |
|
|
777
|
+
| `ctx.notifyResourceUpdated` | `function \| undefined` | Always in handler ctx; delivery request-scoped **and** limited to URIs the client subscribed to |
|
|
713
778
|
| `ctx.notifyPromptListChanged` | `function \| undefined` | Always in handler ctx; delivery request-scoped |
|
|
714
779
|
| `ctx.notifyToolListChanged` | `function \| undefined` | Always in handler ctx; delivery request-scoped |
|
|
715
|
-
| `ctx.progress` | `ContextProgress \| undefined` | Tool defined with `task: true` |
|
|
716
780
|
| `ctx.uri` | `URL \| undefined` | Resource handlers only |
|
|
717
781
|
| `ctx.fail` | `(reason, msg?, data?, opts?) => McpError` | Definition declares `errors[]` contract |
|
|
718
782
|
| `ctx.recoveryFor` | `(reason) => { recovery: { hint } } \| {}` | Always (no-op when no contract); strictly typed on `HandlerContext<R>` |
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
MCP definition linter rules reference. Use when `bun run lint:mcp` or `bun run devcheck` reports a lint error or warning (`format-parity`, `schema-is-object`, `name-format`, `server-json-*`, etc.) and you need to understand the rule, its severity, and how to fix it. Every rule ID the linter emits has an entry in this doc.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.10"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -789,7 +789,7 @@ The diagnostic message includes the declared reason(s) for the code so you can c
|
|
|
789
789
|
|
|
790
790
|
## Enrichment rules
|
|
791
791
|
|
|
792
|
-
Validate the `enrichment` block — the success-path counterpart to `errors[]`. Enrichment fields are merged into `structuredContent` and advertised
|
|
792
|
+
Validate the `enrichment` block — the success-path counterpart to `errors[]`. Enrichment fields are merged into `structuredContent` and folded into the advertised `outputSchema`, so the linter guards the block's shape and its disjointness from `output`. See `api-context`'s `ctx.enrich` and `add-tool`'s **Tool Response Design**.
|
|
793
793
|
|
|
794
794
|
### enrichment-type
|
|
795
795
|
|
|
@@ -4,14 +4,14 @@ description: >
|
|
|
4
4
|
Catalog of OpenTelemetry instrumentation built into framework `@cyanheads/mcp-ts-core` — spans, metrics, completion logs, env config, runtime caveats, custom instrumentation patterns, and cardinality rules. Use when enabling OTel export, adding custom spans or metrics in services, debugging missing telemetry, looking up attribute names, or deciding what's safe to put on a metric attribute vs. a span.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.4"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
## Overview
|
|
13
13
|
|
|
14
|
-
The framework auto-instruments every tool, resource, prompt, storage, LLM, speech, and graph call — each gets its own span and the standard counters/histograms. HTTP server requests pick up spans from `HttpInstrumentation` (all Node.js HTTP traffic, skips `/healthz`) plus `httpInstrumentationMiddleware` from `@hono/otel` on the MCP HTTP endpoint when installed (optional Tier 3 peer — `bun add @hono/otel`). On Bun, `HttpInstrumentation` silently no-ops and `@hono/otel` is the only HTTP coverage. Auth checks
|
|
14
|
+
The framework auto-instruments every tool, resource, prompt, storage, LLM, speech, and graph call — each gets its own span and the standard counters/histograms. HTTP server requests pick up spans from `HttpInstrumentation` (all Node.js HTTP traffic, skips `/healthz`) plus `httpInstrumentationMiddleware` from `@hono/otel` on the MCP HTTP endpoint when installed (optional Tier 3 peer — `bun add @hono/otel`). On Bun, `HttpInstrumentation` silently no-ops and `@hono/otel` is the only HTTP coverage. Auth checks and session lifecycle are tracked as **metrics only** — auth decorates the active HTTP span with attributes, sessions emit counters.
|
|
15
15
|
|
|
16
16
|
`requestId`, `traceId`, and `tenantId` correlate automatically across spans, metrics, and logs. Pino logs get `trace_id`/`span_id` injected when a span is active.
|
|
17
17
|
|
|
@@ -61,15 +61,17 @@ Every handler call gets a span. Nested operations (storage, graph, LLM) become c
|
|
|
61
61
|
|
|
62
62
|
| Span name | Source | Key attributes |
|
|
63
63
|
|:----------|:-------|:---------------|
|
|
64
|
-
| `tool_execution:<tool>` | every tool call | `mcp.tool.input_bytes`, `mcp.tool.output_bytes`, `mcp.tool.duration_ms`, `mcp.tool.success`, `mcp.tool.error_code`, `mcp.tool.partial_success`, `mcp.tool.batch.{succeeded,failed}_count` |
|
|
65
|
-
| `resource_read:<resource>` | every resource handler | `mcp.resource.uri`, `mcp.resource.mime_type`, `mcp.resource.size_bytes`, `mcp.resource.duration_ms`, `mcp.resource.success`, `mcp.resource.error_code` |
|
|
66
|
-
| `prompt_generation:<prompt>` | every prompt handler | `mcp.prompt.input_bytes`, `mcp.prompt.output_bytes`, `mcp.prompt.message_count`, `mcp.prompt.duration_ms`, `mcp.prompt.success`, `mcp.prompt.error_code` |
|
|
64
|
+
| `tool_execution:<tool>` | every tool call | `mcp.tool.input_bytes`, `mcp.tool.output_bytes`, `mcp.tool.duration_ms`, `mcp.tool.success`, `mcp.tool.error_code`, `mcp.tool.input_required`, `mcp.tool.partial_success`, `mcp.tool.batch.{succeeded,failed}_count` |
|
|
65
|
+
| `resource_read:<resource>` | every resource handler | `mcp.resource.uri`, `mcp.resource.mime_type`, `mcp.resource.size_bytes`, `mcp.resource.duration_ms`, `mcp.resource.success`, `mcp.resource.error_code`, `mcp.resource.input_required` |
|
|
66
|
+
| `prompt_generation:<prompt>` | every prompt handler | `mcp.prompt.input_bytes`, `mcp.prompt.output_bytes`, `mcp.prompt.message_count`, `mcp.prompt.duration_ms`, `mcp.prompt.success`, `mcp.prompt.error_code`, `mcp.prompt.input_required` |
|
|
67
67
|
| `storage:<op>` | `StorageService` (every call) | `mcp.storage.operation`, `mcp.storage.duration_ms`, `mcp.storage.success`, `mcp.storage.key_count` (batch ops) |
|
|
68
68
|
| `graph:<op>` | `GraphService` (every call) | `mcp.graph.operation`, `mcp.graph.duration_ms`, `mcp.graph.success` |
|
|
69
69
|
| `gen_ai.chat_completion` | OpenRouter LLM provider | `gen_ai.system=openrouter`, `gen_ai.request.model`, `gen_ai.request.{max_tokens,temperature,top_p,streaming}`, `gen_ai.response.model`, `gen_ai.usage.{input,output,total}_tokens` |
|
|
70
70
|
| `speech:tts` | ElevenLabs provider | `mcp.speech.provider`, `mcp.speech.operation`, `mcp.speech.input_bytes`, `mcp.speech.output_bytes`, `mcp.speech.duration_ms`, `mcp.speech.success` |
|
|
71
71
|
| `speech:stt` | Whisper provider | same as `speech:tts` |
|
|
72
72
|
|
|
73
|
+
A handler that ends its round with `ctx.requestInput(...)` closes its span `OK` with `mcp.*.input_required` set — no recorded exception, no error-counter increment. Multi-round-trip input is protocol control flow, so it never inflates error rates; split on that attribute to tell an incomplete round from a completed call.
|
|
74
|
+
|
|
73
75
|
Trace context propagates across boundaries via W3C `traceparent` headers. See `api-utils` → `telemetry/trace` for `withSpan`, `buildTraceparent`, `extractTraceparent`, `createContextWithParentTrace`, `injectCurrentContextInto`, `runInContext` signatures.
|
|
74
76
|
|
|
75
77
|
---
|
|
@@ -118,7 +120,7 @@ All custom metrics are namespaced `mcp.*` (or `process.*` / `http.client.*` wher
|
|
|
118
120
|
| `mcp.graph.duration` | histogram | `ms` | `mcp.graph.operation`, `mcp.graph.success` |
|
|
119
121
|
| `mcp.graph.errors` | counter | `{errors}` | `mcp.graph.operation` |
|
|
120
122
|
|
|
121
|
-
### Transport, auth, sessions
|
|
123
|
+
### Transport, auth, sessions
|
|
122
124
|
|
|
123
125
|
| Metric | Type | Unit | Attributes |
|
|
124
126
|
|:-------|:-----|:-----|:-----------|
|
|
@@ -128,12 +130,6 @@ All custom metrics are namespaced `mcp.*` (or `process.*` / `http.client.*` wher
|
|
|
128
130
|
| `mcp.session.duration` | histogram | `s` | — |
|
|
129
131
|
| `mcp.sessions.active` | observable gauge | `{sessions}` | — |
|
|
130
132
|
| `mcp.heartbeat.failures` | counter | `{failures}` | `mcp.connection.transport` (`stdio`/`http`) |
|
|
131
|
-
| `mcp.http.close_failures` | counter | `{failures}` | `surface` (`transport`/`server`), `trigger` (`success`/`error`/`sse-abort`) — per-request close threw or timed out |
|
|
132
|
-
| `mcp.http.per_request.created` | counter | `{instances}` | `kind` (`server`/`transport`) — per-request `McpServer` and `McpSessionTransport` instances created |
|
|
133
|
-
| `mcp.http.per_request.finalized` | counter | `{instances}` | `kind` (`server`/`transport`) — per-request instances reclaimed by GC; persistent gap vs `created` indicates a leak |
|
|
134
|
-
| `mcp.tasks.created` | counter | `{tasks}` | `mcp.task.store_type` (`in-memory`/`storage`) |
|
|
135
|
-
| `mcp.tasks.status_changes` | counter | `{transitions}` | `mcp.task.status`, `mcp.task.store_type` |
|
|
136
|
-
| `mcp.tasks.active` | observable gauge | `{tasks}` | — (in-memory store only) |
|
|
137
133
|
|
|
138
134
|
### Errors, rate limits, HTTP client
|
|
139
135
|
|