@cyanheads/mcp-ts-core 0.12.7 → 0.12.9
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 +10 -5
- package/CLAUDE.md +10 -5
- package/README.md +12 -5
- package/changelog/0.12.x/0.12.8.md +55 -0
- package/changelog/0.12.x/0.12.9.md +36 -0
- package/dist/config/index.d.ts +3 -34
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +4 -26
- package/dist/config/index.js.map +1 -1
- package/dist/core/app.d.ts +0 -8
- package/dist/core/app.d.ts.map +1 -1
- package/dist/core/app.js +0 -7
- package/dist/core/app.js.map +1 -1
- package/dist/core/serverManifest.d.ts +0 -7
- package/dist/core/serverManifest.d.ts.map +1 -1
- package/dist/core/serverManifest.js +1 -13
- package/dist/core/serverManifest.js.map +1 -1
- package/dist/linter/rules/enrichment-rules.js +2 -2
- package/dist/linter/rules/enrichment-rules.js.map +1 -1
- package/dist/linter/rules/format-parity-rules.d.ts.map +1 -1
- package/dist/linter/rules/format-parity-rules.js +14 -36
- package/dist/linter/rules/format-parity-rules.js.map +1 -1
- package/dist/linter/rules/prompt-rules.d.ts +1 -1
- package/dist/linter/rules/prompt-rules.d.ts.map +1 -1
- package/dist/linter/rules/prompt-rules.js +2 -19
- package/dist/linter/rules/prompt-rules.js.map +1 -1
- package/dist/linter/rules/resource-rules.d.ts +1 -1
- package/dist/linter/rules/resource-rules.d.ts.map +1 -1
- package/dist/linter/rules/resource-rules.js +9 -39
- package/dist/linter/rules/resource-rules.js.map +1 -1
- package/dist/linter/rules/schema-rules.d.ts +22 -2
- package/dist/linter/rules/schema-rules.d.ts.map +1 -1
- package/dist/linter/rules/schema-rules.js +28 -5
- package/dist/linter/rules/schema-rules.js.map +1 -1
- package/dist/linter/rules/tool-rules.d.ts +1 -1
- package/dist/linter/rules/tool-rules.d.ts.map +1 -1
- package/dist/linter/rules/tool-rules.js +13 -41
- package/dist/linter/rules/tool-rules.js.map +1 -1
- package/dist/linter/validate.d.ts.map +1 -1
- package/dist/linter/validate.js +22 -42
- package/dist/linter/validate.js.map +1 -1
- package/dist/mcp-server/apps/appBuilders.d.ts.map +1 -1
- package/dist/mcp-server/apps/appBuilders.js +2 -16
- package/dist/mcp-server/apps/appBuilders.js.map +1 -1
- package/dist/mcp-server/handlerContext.d.ts +66 -0
- package/dist/mcp-server/handlerContext.d.ts.map +1 -0
- package/dist/mcp-server/handlerContext.js +71 -0
- package/dist/mcp-server/handlerContext.js.map +1 -0
- package/dist/mcp-server/inputRequired.d.ts +7 -1
- package/dist/mcp-server/inputRequired.d.ts.map +1 -1
- package/dist/mcp-server/inputRequired.js +10 -3
- package/dist/mcp-server/inputRequired.js.map +1 -1
- package/dist/mcp-server/resources/resource-registration.d.ts +2 -2
- package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -1
- package/dist/mcp-server/resources/resource-registration.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts +14 -43
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +11 -50
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
- package/dist/mcp-server/tools/tool-registration.d.ts +5 -9
- package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/tool-registration.js +9 -11
- package/dist/mcp-server/tools/tool-registration.js.map +1 -1
- package/dist/mcp-server/tools/utils/schemaShape.d.ts +21 -0
- package/dist/mcp-server/tools/utils/schemaShape.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/schemaShape.js +8 -6
- package/dist/mcp-server/tools/utils/schemaShape.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +15 -43
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js +31 -72
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.js +2 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.js.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.js +70 -2
- package/dist/mcp-server/transports/http/httpTransport.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 +2 -1
- package/dist/mcp-server/transports/http/landing-page/handler.js.map +1 -1
- package/dist/mcp-server/transports/http/landing-page/sections/connect.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/landing-page/sections/connect.js +9 -2
- package/dist/mcp-server/transports/http/landing-page/sections/connect.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 -1
- package/dist/mcp-server/transports/http/protectedResourceMetadata.js.map +1 -1
- package/dist/mcp-server/transports/http/publicOrigin.d.ts +11 -0
- package/dist/mcp-server/transports/http/publicOrigin.d.ts.map +1 -0
- package/dist/mcp-server/transports/http/publicOrigin.js +13 -0
- package/dist/mcp-server/transports/http/publicOrigin.js.map +1 -0
- package/dist/mcp-server/transports/http/serverCard.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/serverCard.js +2 -1
- package/dist/mcp-server/transports/http/serverCard.js.map +1 -1
- package/dist/mcp-server/transports/http/sessionIdUtils.d.ts +4 -0
- package/dist/mcp-server/transports/http/sessionIdUtils.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/sessionIdUtils.js +3 -13
- package/dist/mcp-server/transports/http/sessionIdUtils.js.map +1 -1
- package/dist/mcp-server/transports/http/sessionStore.d.ts +10 -2
- package/dist/mcp-server/transports/http/sessionStore.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/sessionStore.js.map +1 -1
- package/dist/mcp-server/transports/manager.d.ts +0 -3
- package/dist/mcp-server/transports/manager.d.ts.map +1 -1
- package/dist/mcp-server/transports/manager.js +0 -7
- package/dist/mcp-server/transports/manager.js.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.d.ts +14 -0
- package/dist/services/canvas/core/CanvasRegistry.d.ts.map +1 -1
- package/dist/services/canvas/core/CanvasRegistry.js +3 -2
- package/dist/services/canvas/core/CanvasRegistry.js.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts +16 -0
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.d.ts.map +1 -1
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js +78 -103
- package/dist/services/canvas/providers/duckdb/DuckdbProvider.js.map +1 -1
- package/dist/services/graph/core/GraphService.d.ts +3 -3
- package/dist/services/graph/core/GraphService.js +3 -3
- package/dist/services/graph/types.d.ts +2 -79
- package/dist/services/graph/types.d.ts.map +1 -1
- package/dist/services/graph/types.js +2 -2
- package/dist/services/index.d.ts +1 -2
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +0 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/mirror/sqlite/handle.d.ts.map +1 -1
- package/dist/services/mirror/sqlite/handle.js +27 -39
- package/dist/services/mirror/sqlite/handle.js.map +1 -1
- package/dist/services/mirror/sqlite/sqliteMirrorStore.js +8 -9
- package/dist/services/mirror/sqlite/sqliteMirrorStore.js.map +1 -1
- package/dist/services/mirror/types.d.ts +5 -1
- package/dist/services/mirror/types.d.ts.map +1 -1
- package/dist/services/speech/core/ISpeechProvider.d.ts +0 -24
- package/dist/services/speech/core/ISpeechProvider.d.ts.map +1 -1
- package/dist/services/speech/core/ISpeechProvider.js +1 -28
- package/dist/services/speech/core/ISpeechProvider.js.map +1 -1
- package/dist/services/speech/core/SpeechService.d.ts.map +1 -1
- package/dist/services/speech/core/SpeechService.js +5 -8
- package/dist/services/speech/core/SpeechService.js.map +1 -1
- package/dist/services/speech/providers/elevenlabs.provider.d.ts.map +1 -1
- package/dist/services/speech/providers/elevenlabs.provider.js +1 -0
- package/dist/services/speech/providers/elevenlabs.provider.js.map +1 -1
- package/dist/services/speech/types.d.ts +2 -19
- package/dist/services/speech/types.d.ts.map +1 -1
- package/dist/storage/core/providerHelpers.d.ts +52 -0
- package/dist/storage/core/providerHelpers.d.ts.map +1 -0
- package/dist/storage/core/providerHelpers.js +96 -0
- package/dist/storage/core/providerHelpers.js.map +1 -0
- package/dist/storage/providers/cloudflare/d1Provider.d.ts.map +1 -1
- package/dist/storage/providers/cloudflare/d1Provider.js +1 -4
- package/dist/storage/providers/cloudflare/d1Provider.js.map +1 -1
- package/dist/storage/providers/cloudflare/kvProvider.d.ts.map +1 -1
- package/dist/storage/providers/cloudflare/kvProvider.js +4 -31
- 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 +8 -48
- package/dist/storage/providers/cloudflare/r2Provider.js.map +1 -1
- package/dist/storage/providers/fileSystem/fileSystemProvider.d.ts +1 -1
- package/dist/storage/providers/fileSystem/fileSystemProvider.d.ts.map +1 -1
- package/dist/storage/providers/fileSystem/fileSystemProvider.js +17 -86
- package/dist/storage/providers/fileSystem/fileSystemProvider.js.map +1 -1
- package/dist/storage/providers/inMemory/inMemoryProvider.d.ts.map +1 -1
- package/dist/storage/providers/inMemory/inMemoryProvider.js +5 -38
- package/dist/storage/providers/inMemory/inMemoryProvider.js.map +1 -1
- package/dist/storage/providers/supabase/supabaseProvider.d.ts.map +1 -1
- package/dist/storage/providers/supabase/supabaseProvider.js +1 -4
- package/dist/storage/providers/supabase/supabaseProvider.js.map +1 -1
- package/dist/testing/fuzz.d.ts.map +1 -1
- package/dist/testing/fuzz.js +17 -31
- package/dist/testing/fuzz.js.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +4 -26
- package/dist/testing/index.js.map +1 -1
- package/dist/utils/internal/error-handler/types.d.ts +0 -4
- package/dist/utils/internal/error-handler/types.d.ts.map +1 -1
- package/dist/utils/internal/logger.d.ts.map +1 -1
- package/dist/utils/internal/logger.js +2 -16
- package/dist/utils/internal/logger.js.map +1 -1
- package/dist/utils/internal/performance.d.ts +9 -32
- package/dist/utils/internal/performance.d.ts.map +1 -1
- package/dist/utils/internal/performance.js +175 -297
- package/dist/utils/internal/performance.js.map +1 -1
- package/dist/utils/network/fetchWithTimeout.js +1 -1
- package/dist/utils/network/retry.js +1 -1
- package/dist/utils/security/idGenerator.d.ts +3 -1
- package/dist/utils/security/idGenerator.d.ts.map +1 -1
- package/dist/utils/security/idGenerator.js +35 -43
- package/dist/utils/security/idGenerator.js.map +1 -1
- package/dist/utils/security/sanitization.d.ts +0 -7
- package/dist/utils/security/sanitization.d.ts.map +1 -1
- package/dist/utils/security/sanitization.js +4 -31
- package/dist/utils/security/sanitization.js.map +1 -1
- package/dist/utils/security/sensitiveFields.d.ts +14 -0
- package/dist/utils/security/sensitiveFields.d.ts.map +1 -0
- package/dist/utils/security/sensitiveFields.js +31 -0
- package/dist/utils/security/sensitiveFields.js.map +1 -0
- package/dist/utils/telemetry/trace.d.ts +8 -10
- package/dist/utils/telemetry/trace.d.ts.map +1 -1
- package/dist/utils/telemetry/trace.js +19 -18
- package/dist/utils/telemetry/trace.js.map +1 -1
- package/dist/utils/types/guards.d.ts +0 -102
- package/dist/utils/types/guards.d.ts.map +1 -1
- package/dist/utils/types/guards.js +0 -114
- package/dist/utils/types/guards.js.map +1 -1
- package/package.json +11 -11
- package/scripts/devcheck.ts +21 -14
- package/skills/add-provider/SKILL.md +18 -4
- package/skills/add-tool/SKILL.md +4 -4
- package/skills/api-config/SKILL.md +4 -18
- package/skills/api-errors/SKILL.md +2 -1
- package/skills/api-mirror/SKILL.md +3 -1
- package/skills/api-services/SKILL.md +1 -1
- package/skills/api-services/references/speech.md +1 -2
- package/skills/api-telemetry/SKILL.md +2 -2
- package/skills/api-utils/SKILL.md +2 -2
- package/skills/code-simplifier/SKILL.md +47 -20
- package/skills/design-mcp-server/SKILL.md +59 -101
- package/skills/field-test/SKILL.md +101 -17
- package/skills/git-wrapup/SKILL.md +68 -29
- package/skills/orchestrations/SKILL.md +17 -6
- package/skills/orchestrations/workflows/field-test-fix.md +6 -4
- package/skills/orchestrations/workflows/fix-wrapup-release.md +6 -4
- package/skills/orchestrations/workflows/greenfield-build.md +2 -2
- package/skills/orchestrations/workflows/maintenance-release.md +4 -2
- package/skills/polish-docs-meta/SKILL.md +1 -1
- package/skills/polish-docs-meta/references/package-meta.md +1 -1
- package/skills/polish-docs-meta/references/readme.md +2 -2
- package/skills/release-and-publish/SKILL.md +104 -23
- package/skills/release-pr-review/SKILL.md +147 -0
- package/skills/security-pass/SKILL.md +2 -2
- package/templates/AGENTS.md +5 -3
- package/templates/CLAUDE.md +5 -3
- package/templates/package.json +1 -1
- package/dist/mcp-server/transports/ITransport.d.ts +0 -15
- package/dist/mcp-server/transports/ITransport.d.ts.map +0 -1
- package/dist/mcp-server/transports/ITransport.js +0 -2
- package/dist/mcp-server/transports/ITransport.js.map +0 -1
- package/dist/services/llm/types.d.ts +0 -16
- package/dist/services/llm/types.d.ts.map +0 -1
- package/dist/services/llm/types.js +0 -9
- package/dist/services/llm/types.js.map +0 -1
- package/dist/utils/internal/health.d.ts +0 -60
- package/dist/utils/internal/health.d.ts.map +0 -1
- package/dist/utils/internal/health.js +0 -46
- package/dist/utils/internal/health.js.map +0 -1
|
@@ -54,56 +54,6 @@ export declare function isRecord(value: unknown): value is Record<string, unknow
|
|
|
54
54
|
* ```
|
|
55
55
|
*/
|
|
56
56
|
export declare function hasProperty<K extends PropertyKey>(obj: unknown, key: K): obj is Record<K, unknown>;
|
|
57
|
-
/**
|
|
58
|
-
* Type guard to check if an object has a property of a specific type.
|
|
59
|
-
*
|
|
60
|
-
* @param obj - Object to check
|
|
61
|
-
* @param key - Property key to look for
|
|
62
|
-
* @param typeGuard - Type guard function for the property value
|
|
63
|
-
* @returns True if object has the property and it matches the type
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* ```typescript
|
|
67
|
-
* if (hasPropertyOfType(obj, 'count', (v): v is number => typeof v === 'number')) {
|
|
68
|
-
* // obj.count is now typed as number
|
|
69
|
-
* console.log(obj.count + 1);
|
|
70
|
-
* }
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
export declare function hasPropertyOfType<K extends PropertyKey, T>(obj: unknown, key: K, typeGuard: (value: unknown) => value is T): obj is Record<K, T>;
|
|
74
|
-
/**
|
|
75
|
-
* Type guard to check if a value is a string.
|
|
76
|
-
*
|
|
77
|
-
* @param value - Value to check
|
|
78
|
-
* @returns True if value is a string
|
|
79
|
-
*
|
|
80
|
-
* @example
|
|
81
|
-
* ```typescript
|
|
82
|
-
* if (isString(value)) {
|
|
83
|
-
* // value is now typed as string
|
|
84
|
-
* console.log(value.toUpperCase());
|
|
85
|
-
* }
|
|
86
|
-
* ```
|
|
87
|
-
*/
|
|
88
|
-
export declare function isString(value: unknown): value is string;
|
|
89
|
-
/**
|
|
90
|
-
* Type guard to check if a value is a number.
|
|
91
|
-
*
|
|
92
|
-
* `NaN` is explicitly excluded — `typeof NaN === 'number'` is true in JavaScript,
|
|
93
|
-
* but `NaN` is almost never a valid value in the contexts where this guard is used.
|
|
94
|
-
*
|
|
95
|
-
* @param value - Value to check
|
|
96
|
-
* @returns True if value is a finite or infinite number (excluding NaN)
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```typescript
|
|
100
|
-
* if (isNumber(value)) {
|
|
101
|
-
* // value is now typed as number (NaN excluded)
|
|
102
|
-
* console.log(value.toFixed(2));
|
|
103
|
-
* }
|
|
104
|
-
* ```
|
|
105
|
-
*/
|
|
106
|
-
export declare function isNumber(value: unknown): value is number;
|
|
107
57
|
/**
|
|
108
58
|
* Type guard to check if an error is an AggregateError.
|
|
109
59
|
*
|
|
@@ -140,22 +90,6 @@ export declare function isAggregateError(error: unknown): error is Error & {
|
|
|
140
90
|
export declare function isErrorWithCode(error: unknown): error is Error & {
|
|
141
91
|
code: unknown;
|
|
142
92
|
};
|
|
143
|
-
/**
|
|
144
|
-
* Type guard to check if an error has a status property.
|
|
145
|
-
*
|
|
146
|
-
* @param error - Error to check
|
|
147
|
-
* @returns True if error has a status property
|
|
148
|
-
*
|
|
149
|
-
* @example
|
|
150
|
-
* ```typescript
|
|
151
|
-
* if (isErrorWithStatus(error)) {
|
|
152
|
-
* console.log(`HTTP status: ${error.status}`);
|
|
153
|
-
* }
|
|
154
|
-
* ```
|
|
155
|
-
*/
|
|
156
|
-
export declare function isErrorWithStatus(error: unknown): error is Error & {
|
|
157
|
-
status: unknown;
|
|
158
|
-
};
|
|
159
93
|
/**
|
|
160
94
|
* Safely get a property from an object if it exists.
|
|
161
95
|
*
|
|
@@ -170,40 +104,4 @@ export declare function isErrorWithStatus(error: unknown): error is Error & {
|
|
|
170
104
|
* ```
|
|
171
105
|
*/
|
|
172
106
|
export declare function getProperty<K extends PropertyKey>(obj: unknown, key: K): unknown;
|
|
173
|
-
/**
|
|
174
|
-
* Safely get a string property from an object.
|
|
175
|
-
*
|
|
176
|
-
* @param obj - Object to get property from
|
|
177
|
-
* @param key - Property key
|
|
178
|
-
* @returns String value or undefined if property doesn't exist or is not a string
|
|
179
|
-
*
|
|
180
|
-
* @example
|
|
181
|
-
* ```typescript
|
|
182
|
-
* const traceId = getStringProperty(context, 'traceId');
|
|
183
|
-
* if (traceId) {
|
|
184
|
-
* // traceId is typed as string
|
|
185
|
-
* console.log(traceId.toUpperCase());
|
|
186
|
-
* }
|
|
187
|
-
* ```
|
|
188
|
-
*/
|
|
189
|
-
export declare function getStringProperty<K extends PropertyKey>(obj: unknown, key: K): string | undefined;
|
|
190
|
-
/**
|
|
191
|
-
* Safely get a number property from an object.
|
|
192
|
-
*
|
|
193
|
-
* Returns `undefined` if the property is absent, not a number, or is `NaN`.
|
|
194
|
-
*
|
|
195
|
-
* @param obj - Object to get property from
|
|
196
|
-
* @param key - Property key
|
|
197
|
-
* @returns Number value or undefined if property doesn't exist, is not a number, or is NaN
|
|
198
|
-
*
|
|
199
|
-
* @example
|
|
200
|
-
* ```typescript
|
|
201
|
-
* const retries = getNumberProperty(config, 'maxRetries');
|
|
202
|
-
* if (retries !== undefined) {
|
|
203
|
-
* // retries is typed as number
|
|
204
|
-
* console.log(`Max retries: ${retries}`);
|
|
205
|
-
* }
|
|
206
|
-
* ```
|
|
207
|
-
*/
|
|
208
|
-
export declare function getNumberProperty<K extends PropertyKey>(obj: unknown, key: K): number | undefined;
|
|
209
107
|
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../../src/utils/types/guards.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAExD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAC/C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,CAAC,GACL,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAE3B;AAED
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../../src/utils/types/guards.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAExD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAC/C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,CAAC,GACL,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAE3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,GAAG;IAAE,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAEvF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAElF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAEhF"}
|
|
@@ -60,62 +60,6 @@ export function isRecord(value) {
|
|
|
60
60
|
export function hasProperty(obj, key) {
|
|
61
61
|
return isObject(obj) && key in obj;
|
|
62
62
|
}
|
|
63
|
-
/**
|
|
64
|
-
* Type guard to check if an object has a property of a specific type.
|
|
65
|
-
*
|
|
66
|
-
* @param obj - Object to check
|
|
67
|
-
* @param key - Property key to look for
|
|
68
|
-
* @param typeGuard - Type guard function for the property value
|
|
69
|
-
* @returns True if object has the property and it matches the type
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```typescript
|
|
73
|
-
* if (hasPropertyOfType(obj, 'count', (v): v is number => typeof v === 'number')) {
|
|
74
|
-
* // obj.count is now typed as number
|
|
75
|
-
* console.log(obj.count + 1);
|
|
76
|
-
* }
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
|
-
export function hasPropertyOfType(obj, key, typeGuard) {
|
|
80
|
-
return hasProperty(obj, key) && typeGuard(obj[key]);
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Type guard to check if a value is a string.
|
|
84
|
-
*
|
|
85
|
-
* @param value - Value to check
|
|
86
|
-
* @returns True if value is a string
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* ```typescript
|
|
90
|
-
* if (isString(value)) {
|
|
91
|
-
* // value is now typed as string
|
|
92
|
-
* console.log(value.toUpperCase());
|
|
93
|
-
* }
|
|
94
|
-
* ```
|
|
95
|
-
*/
|
|
96
|
-
export function isString(value) {
|
|
97
|
-
return typeof value === 'string';
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Type guard to check if a value is a number.
|
|
101
|
-
*
|
|
102
|
-
* `NaN` is explicitly excluded — `typeof NaN === 'number'` is true in JavaScript,
|
|
103
|
-
* but `NaN` is almost never a valid value in the contexts where this guard is used.
|
|
104
|
-
*
|
|
105
|
-
* @param value - Value to check
|
|
106
|
-
* @returns True if value is a finite or infinite number (excluding NaN)
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* ```typescript
|
|
110
|
-
* if (isNumber(value)) {
|
|
111
|
-
* // value is now typed as number (NaN excluded)
|
|
112
|
-
* console.log(value.toFixed(2));
|
|
113
|
-
* }
|
|
114
|
-
* ```
|
|
115
|
-
*/
|
|
116
|
-
export function isNumber(value) {
|
|
117
|
-
return typeof value === 'number' && !Number.isNaN(value);
|
|
118
|
-
}
|
|
119
63
|
/**
|
|
120
64
|
* Type guard to check if an error is an AggregateError.
|
|
121
65
|
*
|
|
@@ -152,22 +96,6 @@ export function isAggregateError(error) {
|
|
|
152
96
|
export function isErrorWithCode(error) {
|
|
153
97
|
return error instanceof Error && hasProperty(error, 'code');
|
|
154
98
|
}
|
|
155
|
-
/**
|
|
156
|
-
* Type guard to check if an error has a status property.
|
|
157
|
-
*
|
|
158
|
-
* @param error - Error to check
|
|
159
|
-
* @returns True if error has a status property
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* ```typescript
|
|
163
|
-
* if (isErrorWithStatus(error)) {
|
|
164
|
-
* console.log(`HTTP status: ${error.status}`);
|
|
165
|
-
* }
|
|
166
|
-
* ```
|
|
167
|
-
*/
|
|
168
|
-
export function isErrorWithStatus(error) {
|
|
169
|
-
return error instanceof Error && hasProperty(error, 'status');
|
|
170
|
-
}
|
|
171
99
|
/**
|
|
172
100
|
* Safely get a property from an object if it exists.
|
|
173
101
|
*
|
|
@@ -184,46 +112,4 @@ export function isErrorWithStatus(error) {
|
|
|
184
112
|
export function getProperty(obj, key) {
|
|
185
113
|
return hasProperty(obj, key) ? obj[key] : undefined;
|
|
186
114
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Safely get a string property from an object.
|
|
189
|
-
*
|
|
190
|
-
* @param obj - Object to get property from
|
|
191
|
-
* @param key - Property key
|
|
192
|
-
* @returns String value or undefined if property doesn't exist or is not a string
|
|
193
|
-
*
|
|
194
|
-
* @example
|
|
195
|
-
* ```typescript
|
|
196
|
-
* const traceId = getStringProperty(context, 'traceId');
|
|
197
|
-
* if (traceId) {
|
|
198
|
-
* // traceId is typed as string
|
|
199
|
-
* console.log(traceId.toUpperCase());
|
|
200
|
-
* }
|
|
201
|
-
* ```
|
|
202
|
-
*/
|
|
203
|
-
export function getStringProperty(obj, key) {
|
|
204
|
-
const value = getProperty(obj, key);
|
|
205
|
-
return isString(value) ? value : undefined;
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Safely get a number property from an object.
|
|
209
|
-
*
|
|
210
|
-
* Returns `undefined` if the property is absent, not a number, or is `NaN`.
|
|
211
|
-
*
|
|
212
|
-
* @param obj - Object to get property from
|
|
213
|
-
* @param key - Property key
|
|
214
|
-
* @returns Number value or undefined if property doesn't exist, is not a number, or is NaN
|
|
215
|
-
*
|
|
216
|
-
* @example
|
|
217
|
-
* ```typescript
|
|
218
|
-
* const retries = getNumberProperty(config, 'maxRetries');
|
|
219
|
-
* if (retries !== undefined) {
|
|
220
|
-
* // retries is typed as number
|
|
221
|
-
* console.log(`Max retries: ${retries}`);
|
|
222
|
-
* }
|
|
223
|
-
* ```
|
|
224
|
-
*/
|
|
225
|
-
export function getNumberProperty(obj, key) {
|
|
226
|
-
const value = getProperty(obj, key);
|
|
227
|
-
return isNumber(value) ? value : undefined;
|
|
228
|
-
}
|
|
229
115
|
//# sourceMappingURL=guards.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../../src/utils/types/guards.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,WAAW,CACzB,GAAY,EACZ,GAAM;IAEN,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC;AACrC,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../../src/utils/types/guards.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,WAAW,CACzB,GAAY,EACZ,GAAM;IAEN,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,KAAK,YAAY,KAAK,IAAI,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/F,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,KAAK,YAAY,KAAK,IAAI,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAwB,GAAY,EAAE,GAAM;IACrE,OAAO,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACtD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/mcp-ts-core",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.9",
|
|
4
4
|
"mcpName": "io.github.cyanheads/mcp-ts-core",
|
|
5
5
|
"description": "Agent-native TypeScript framework for MCP servers. Includes runtime infrastructure and agent skills for building, testing, and shipping servers.",
|
|
6
6
|
"files": [
|
|
@@ -206,14 +206,14 @@
|
|
|
206
206
|
"@opentelemetry/exporter-trace-otlp-http": "^0.222.0",
|
|
207
207
|
"@opentelemetry/instrumentation-http": "^0.222.0",
|
|
208
208
|
"@opentelemetry/instrumentation-pino": "^0.68.0",
|
|
209
|
-
"@opentelemetry/resources": "^2.
|
|
210
|
-
"@opentelemetry/sdk-metrics": "^2.
|
|
209
|
+
"@opentelemetry/resources": "^2.11.0",
|
|
210
|
+
"@opentelemetry/sdk-metrics": "^2.11.0",
|
|
211
211
|
"@opentelemetry/sdk-node": "^0.222.0",
|
|
212
|
-
"@opentelemetry/sdk-trace-node": "^2.
|
|
212
|
+
"@opentelemetry/sdk-trace-node": "^2.11.0",
|
|
213
213
|
"@opentelemetry/semantic-conventions": "^1.43.0",
|
|
214
214
|
"@socketsecurity/bun-security-scanner": "^1.1.2",
|
|
215
|
-
"@supabase/supabase-js": "^2.
|
|
216
|
-
"@types/bun": "^1.4.
|
|
215
|
+
"@supabase/supabase-js": "^2.116.0",
|
|
216
|
+
"@types/bun": "^1.4.2",
|
|
217
217
|
"@types/node": "26.4.0",
|
|
218
218
|
"@types/papaparse": "^5.5.2",
|
|
219
219
|
"@types/sanitize-html": "^2.16.1",
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
"execa": "^10.0.1",
|
|
231
231
|
"fast-check": "^4.9.0",
|
|
232
232
|
"fast-xml-parser": "^5.11.1",
|
|
233
|
-
"ignore": "^7.0.
|
|
233
|
+
"ignore": "^7.0.9",
|
|
234
234
|
"js-yaml": "^5.4.1",
|
|
235
235
|
"linkedom": "^0.18.13",
|
|
236
236
|
"node-cron": "^4.6.0",
|
|
@@ -241,7 +241,7 @@
|
|
|
241
241
|
"pino-pretty": "^13.1.3",
|
|
242
242
|
"repomix": "^1.18.0",
|
|
243
243
|
"sanitize-html": "^2.17.7",
|
|
244
|
-
"tsc-alias": "^1.9.
|
|
244
|
+
"tsc-alias": "^1.9.4",
|
|
245
245
|
"typedoc": "^0.28.20",
|
|
246
246
|
"typescript": "^7.0.2",
|
|
247
247
|
"typescript-v6": "npm:typescript@^6.0.3",
|
|
@@ -282,7 +282,7 @@
|
|
|
282
282
|
],
|
|
283
283
|
"packageManager": "bun@1.4.0",
|
|
284
284
|
"engines": {
|
|
285
|
-
"bun": ">=1.
|
|
285
|
+
"bun": ">=1.4.0",
|
|
286
286
|
"node": ">=24.0.0"
|
|
287
287
|
},
|
|
288
288
|
"depcheck": {
|
|
@@ -302,14 +302,14 @@
|
|
|
302
302
|
"dependencies": {
|
|
303
303
|
"@hono/node-server": "^2.1.1",
|
|
304
304
|
"@modelcontextprotocol/client": "^2.0.0",
|
|
305
|
-
"@modelcontextprotocol/ext-apps": "^
|
|
305
|
+
"@modelcontextprotocol/ext-apps": "^2.0.0",
|
|
306
306
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
307
307
|
"@opentelemetry/api": "^1.9.1",
|
|
308
308
|
"dotenv": "^17.4.2",
|
|
309
309
|
"hono": "^4.13.7",
|
|
310
310
|
"jose": "^6.2.12",
|
|
311
311
|
"pino": "^10.3.1",
|
|
312
|
-
"zod": "^4.
|
|
312
|
+
"zod": "^4.6.0"
|
|
313
313
|
},
|
|
314
314
|
"peerDependencies": {
|
|
315
315
|
"@duckdb/node-api": "^1.5.5-r.1",
|
package/scripts/devcheck.ts
CHANGED
|
@@ -437,7 +437,8 @@ interface OutdatedRow {
|
|
|
437
437
|
current: string;
|
|
438
438
|
/** The declared key when attribution is unambiguous, else null. */
|
|
439
439
|
declaredKey: string | null;
|
|
440
|
-
|
|
440
|
+
/** The block the row belongs to; `bun outdated` leaves `prod` rows unmarked. */
|
|
441
|
+
group: DependencyGroup;
|
|
441
442
|
/** The row verbatim, used to key the rendered rewrite back to its line. */
|
|
442
443
|
line: string;
|
|
443
444
|
/** First cell as printed, marker included. */
|
|
@@ -457,11 +458,11 @@ interface OutdatedRow {
|
|
|
457
458
|
*/
|
|
458
459
|
function attributeOutdatedRow(
|
|
459
460
|
target: string,
|
|
460
|
-
group: DependencyGroup
|
|
461
|
+
group: DependencyGroup,
|
|
461
462
|
current: string,
|
|
462
463
|
): Pick<OutdatedRow, 'candidates' | 'declaredKey'> {
|
|
463
464
|
const matches = DECLARED_DEPENDENCIES.filter(
|
|
464
|
-
(declared) => declared.target === target &&
|
|
465
|
+
(declared) => declared.target === target && declared.group === group,
|
|
465
466
|
);
|
|
466
467
|
const candidates = matches.map((declared) => declared.key);
|
|
467
468
|
if (candidates.length <= 1) return { candidates, declaredKey: candidates[0] ?? null };
|
|
@@ -481,7 +482,7 @@ function parseOutdatedRows(output: string): OutdatedRow[] {
|
|
|
481
482
|
const rawName = cells[1] ?? '';
|
|
482
483
|
// Skip table chrome: header row and separator (e.g., "---")
|
|
483
484
|
if (!rawName || rawName === 'Package' || /^-+$/.test(rawName)) continue;
|
|
484
|
-
const group = (OUTDATED_GROUP_MARKER.exec(rawName)?.[1] ??
|
|
485
|
+
const group = (OUTDATED_GROUP_MARKER.exec(rawName)?.[1] ?? 'prod') as DependencyGroup;
|
|
485
486
|
const target = rawName.replace(OUTDATED_GROUP_MARKER, '');
|
|
486
487
|
const current = cells[2] ?? '';
|
|
487
488
|
const update = (cells[3] ?? '').replace(/\*/g, '').trim();
|
|
@@ -514,7 +515,7 @@ function renderOutdatedTable(output: string): string {
|
|
|
514
515
|
const row = attributed.get(line);
|
|
515
516
|
let display = cell.trim();
|
|
516
517
|
if (row?.declaredKey && row.declaredKey !== row.target) {
|
|
517
|
-
display = row.group ? `${row.declaredKey} (${row.group})
|
|
518
|
+
display = row.group === 'prod' ? row.declaredKey : `${row.declaredKey} (${row.group})`;
|
|
518
519
|
}
|
|
519
520
|
return { line, display };
|
|
520
521
|
});
|
|
@@ -552,9 +553,12 @@ function renderOutdatedTable(output: string): string {
|
|
|
552
553
|
* Parses `bun audit` output and classifies high/critical vulnerabilities as
|
|
553
554
|
* direct (in our package.json) or upstream (transitive dependency we can't fix).
|
|
554
555
|
*
|
|
555
|
-
* Bun audit format per vulnerability block
|
|
556
|
-
*
|
|
557
|
-
*
|
|
556
|
+
* Bun audit format per vulnerability block — Bun 1.4 changed the header token
|
|
557
|
+
* and the path separator, so both shapes are accepted:
|
|
558
|
+
* <package> <version-range> ← header, Bun <1.4 (no indent, 2+ spaces before range)
|
|
559
|
+
* <package>@<version> ← header, Bun ≥1.4
|
|
560
|
+
* <parent> › <child> [› ...] ← dependency path (indented; › or, Bun ≥1.4, > = transitive)
|
|
561
|
+
* (direct dependency) ← dependency path of a direct dependency, Bun ≥1.4
|
|
558
562
|
* <severity>: <description> ← advisory (indented)
|
|
559
563
|
*
|
|
560
564
|
* Returns null if parsing yields no results (caller should fall back to default behavior).
|
|
@@ -567,8 +571,10 @@ function classifyAuditVulns(output: string): { direct: string[]; upstream: strin
|
|
|
567
571
|
let i = 0;
|
|
568
572
|
|
|
569
573
|
while (i < lines.length) {
|
|
570
|
-
// Package header: non-indented
|
|
571
|
-
|
|
574
|
+
// Package header: non-indented `name range` (2+ spaces, Bun <1.4) or
|
|
575
|
+
// `name@version` (Bun ≥1.4). A scoped name leads with `@`, so only a
|
|
576
|
+
// later `@` splits the Bun 1.4 form.
|
|
577
|
+
const pkgMatch = lines[i]?.match(/^(@?\w[\w./-]*)(?:\s{2,}|@)(\S.*)$/);
|
|
572
578
|
if (!pkgMatch) {
|
|
573
579
|
i++;
|
|
574
580
|
continue;
|
|
@@ -593,14 +599,15 @@ function classifyAuditVulns(output: string): { direct: string[]; upstream: strin
|
|
|
593
599
|
|
|
594
600
|
if (!hasHighCritical) continue;
|
|
595
601
|
|
|
596
|
-
// Direct if: the vulnerable package is in our package.json,
|
|
597
|
-
//
|
|
602
|
+
// Direct if: the vulnerable package is in our package.json, or any
|
|
603
|
+
// dependency path lacks a transitive separator — U+203A `›` (Bun <1.4)
|
|
604
|
+
// or `>` (Bun ≥1.4). Bun 1.4's literal `(direct dependency)` path has neither.
|
|
598
605
|
const pkgName = pkg ?? '';
|
|
599
|
-
const isDirect = DIRECT_DEPS.has(pkgName) || paths.some((p) =>
|
|
606
|
+
const isDirect = DIRECT_DEPS.has(pkgName) || paths.some((p) => !/[\u203a>]/.test(p));
|
|
600
607
|
if (isDirect) {
|
|
601
608
|
direct.push(`${pkgName} ${versionRange}`);
|
|
602
609
|
} else {
|
|
603
|
-
const via = paths[0]?.split(/\s
|
|
610
|
+
const via = paths[0]?.split(/\s*[\u203a>]\s*/)[0] ?? 'unknown';
|
|
604
611
|
upstream.push(`${pkgName} ${versionRange} (via ${via})`);
|
|
605
612
|
}
|
|
606
613
|
}
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Add a new storage or service provider to the core package. Use when implementing a new backend for StorageService (e.g., a new database) or a new service provider (e.g., a new LLM backend).
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.1"
|
|
8
8
|
audience: internal
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -53,7 +53,20 @@ Provider file location and naming differ by domain:
|
|
|
53
53
|
1. **Identify the provider interface** — read the interface file for the target domain
|
|
54
54
|
(see table above).
|
|
55
55
|
2. **Create the provider file** following the file convention for its domain (see above).
|
|
56
|
-
3. **Implement the interface** — all methods must be implemented.
|
|
56
|
+
3. **Implement the interface** — all methods must be implemented. Storage providers build
|
|
57
|
+
on `src/storage/core/providerHelpers.ts` rather than re-deriving what the existing
|
|
58
|
+
providers share:
|
|
59
|
+
|
|
60
|
+
- `getManyViaGet` / `setManyViaSet` / `deleteManyViaDelete` — the batch methods as a
|
|
61
|
+
parallel fan-out over the single-key methods, for backends with no native batch API.
|
|
62
|
+
- `encodeEnvelope` / `decodeEnvelope` — the TTL envelope for backends with no TTL of their
|
|
63
|
+
own (R2, filesystem). `decodeEnvelope` returns `{ kind: 'expired' }` so the provider can
|
|
64
|
+
delete on read, returns pre-envelope JSON as a plain value, and throws `SyntaxError` on
|
|
65
|
+
invalid JSON so the provider can attach the key to the error it raises.
|
|
66
|
+
- `paginateSortedKeys` — one `list()` page over an already-sorted key set, with the cursor
|
|
67
|
+
for the page that follows.
|
|
68
|
+
- `escapeLikePattern` — escapes `%`, `_`, and `\` in a prefix before a SQL `LIKE`.
|
|
69
|
+
|
|
57
70
|
4. **Lazy-load dependencies** if Tier 3:
|
|
58
71
|
|
|
59
72
|
```typescript
|
|
@@ -94,7 +107,7 @@ Provider file location and naming differ by domain:
|
|
|
94
107
|
`isServerless()` guard:
|
|
95
108
|
|
|
96
109
|
```typescript
|
|
97
|
-
// src/storage/core/storageFactory.ts
|
|
110
|
+
// src/storage/core/storageFactory.ts
|
|
98
111
|
!['in-memory', 'cloudflare-r2', 'cloudflare-kv', 'cloudflare-d1'].includes(providerType)
|
|
99
112
|
```
|
|
100
113
|
|
|
@@ -115,9 +128,10 @@ Provider file location and naming differ by domain:
|
|
|
115
128
|
- [ ] Registered in the correct factory for the domain (see Step 5)
|
|
116
129
|
- [ ] Storage: provider string added to `z.enum` in `src/config/index.ts`
|
|
117
130
|
- [ ] Storage: Worker-compatible array in `storageFactory.ts` updated if applicable
|
|
131
|
+
- [ ] Storage: batch, TTL envelope, paging, and `LIKE` escaping come from `providerHelpers.ts`, not a local copy
|
|
118
132
|
- [ ] Speech: `provider` literal added to `SpeechProviderConfig` union in `types.ts`
|
|
119
133
|
- [ ] LLM: `src/core/app.ts` instantiation logic updated if adding a second LLM provider
|
|
120
134
|
- [ ] Optional peer dependency added to both `peerDependencies` and `peerDependenciesMeta` in `package.json` if Tier 3
|
|
121
135
|
- [ ] `bun run rebuild` succeeds
|
|
122
136
|
- [ ] `bun run devcheck` passes
|
|
123
|
-
- [ ]
|
|
137
|
+
- [ ] Tests added under `tests/unit/storage/providers/{{providerName}}/` (storage) or `tests/unit/services/{{domain}}/providers/{{provider-name}}.provider.test.ts` (LLM / speech), and `bun run test` passes
|
package/skills/add-tool/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold a new MCP tool definition. Use when the user asks to add a tool, create a new tool, or implement a new capability for the server.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "2.
|
|
7
|
+
version: "2.23"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -26,9 +26,9 @@ Tools use the `tool()` builder from `@cyanheads/mcp-ts-core`. Each tool lives in
|
|
|
26
26
|
|
|
27
27
|
Tools use lowercase snake_case with a canonical server/domain prefix: `{server}_{verb}_{noun}` — 3 words.
|
|
28
28
|
|
|
29
|
-
Examples: `pubmed_search_articles`, `pubmed_fetch_fulltext`, `
|
|
29
|
+
Examples: `pubmed_search_articles`, `pubmed_fetch_fulltext`, `clinicaltrials_find_eligible`.
|
|
30
30
|
|
|
31
|
-
The server prefix
|
|
31
|
+
The server prefix is judged on clarity, not length: the brand name or the plain well-known word for the domain both pass (`pubmed_`, `patents_`); an abbreviation fails only when it reads as something else out of context (`loc_`, `ct_`). A fourth segment is fine when the noun is inherently two words (`openfda_search_device_clearances`). When a name resists the schema — can't pick a verb, noun feels generic, the *verb* wants a second word — that's usually a signal the scope is fuzzy; split the tool, rename, or reconsider.
|
|
32
32
|
|
|
33
33
|
For shape selection (Workflow or Instruction variants — standard single-action tools are the default), see the `design-mcp-server` skill's Tool shapes section.
|
|
34
34
|
|
|
@@ -774,7 +774,7 @@ Large payloads burn the agent's context window. Default to curated summaries; of
|
|
|
774
774
|
- **Lists**: Return top N with a total count and pagination cursor, not unbounded arrays
|
|
775
775
|
- **Large objects**: Return key fields by default; accept a `fields` or `verbose` parameter for full data
|
|
776
776
|
- **Binary/blob content**: Return metadata and a reference, not the raw content
|
|
777
|
-
- **Analytical working sets**: When upstream returns more *analytical* rows (data an agent would SQL — aggregate, group, join) than fit in context, `DataCanvas` (`
|
|
777
|
+
- **Analytical working sets**: When upstream returns more *analytical* rows (data an agent would SQL — aggregate, group, join) than fit in context, `DataCanvas` (`core.canvas`, wired in `setup()` via `setCanvas`; Tier 3 — opt-in via `CANVAS_PROVIDER_TYPE=duckdb`) lets you register the rows and return the `canvas_id` plus a preview so the agent can run SQL to slice down without a re-fetch. The `spillover()` helper (`@cyanheads/mcp-ts-core/canvas`) automates the overflow case: drain rows up to a character budget for the inline preview, auto-register the full source on overflow, return both as a discriminated union. **Two gates:** it must be analytical, not a discovery/search surface of categorical metadata (those don't earn a canvas regardless of row count — use MCP-side list filtering or pagination); and a tool emitting a `canvas_id` MUST be paired with a registered `dataframe_query` tool, or the handle is unreachable. Compute distributions or refinement hints across the full result — not the preview — so the agent gets honest aggregate signal on the rows it didn't read. See `api-canvas` for the register / query / export pattern and the spillover flow.
|
|
778
778
|
- **One large document**: When a single call returns one document-shaped record (not a row set) that can overflow context, return a section *outline* — top-level keys + per-section byte size — and let the agent re-call with `sections: [...]` for only what it needs, instead of truncating one surface. `outlineOnOverflow()` with `OUTLINE_VARIANT` / `selectSections()` / `formatOutline()` (`@cyanheads/mcp-ts-core/utils`) measures the payload and returns a `full | outline` result. Declare the tool's `output` as a flat `z.object` with a `kind` discriminator and presence-based optional arms (fold in `OUTLINE_VARIANT.shape.sections` / `.notice`) — `tool()` rejects a `z.discriminatedUnion` output — and render each arm on field presence in `format()` so parity holds. Pure measure + key-slice — Workers-portable, unlike canvas `spillover()`. Use for one fat record; use `spillover()` for a row collection. See the `techniques` skill's `outline-on-overflow` reference.
|
|
779
779
|
|
|
780
780
|
## MCP-side list filtering
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Reference for core and server configuration in `@cyanheads/mcp-ts-core`. Covers env var tables with defaults, priority order, server-specific Zod schema pattern, and Workers lazy-parsing requirement.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.16"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -95,7 +95,6 @@ await createApp({
|
|
|
95
95
|
| `MCP_HTTP_RESUMABILITY` | `mcpHttpResumability` | `true` | SSE stream replay under stateful HTTP. On by default — selecting a session mode is the opt-in. Kill switch only; no effect on stateless serving or the session-less 2026-07-28 era |
|
|
96
96
|
| `MCP_HTTP_RESUMABILITY_MAX_EVENTS` | `mcpHttpResumabilityMaxEvents` | `512` | Events retained per session for replay; oldest evicted first. Lower it on a server whose tools return large results |
|
|
97
97
|
| `MCP_HTTP_RESUMABILITY_TTL_MS` | `mcpHttpResumabilityTtlMs` | `300000` | 5 min; how long a retained event stays replayable |
|
|
98
|
-
| `MCP_RESPONSE_VERBOSITY` | `mcpResponseVerbosity` | `standard` | `minimal` \| `standard` \| `full` |
|
|
99
98
|
| `MCP_ALLOWED_ORIGINS` | `mcpAllowedOrigins` | — | Comma-separated list; omit to allow all |
|
|
100
99
|
| `MCP_SERVER_RESOURCE_IDENTIFIER` | `mcpServerResourceIdentifier` | — | RFC 8707 resource indicator URL |
|
|
101
100
|
| `MCP_PUBLIC_URL` | `mcpPublicUrl` | — | Public-facing origin for reverse proxies (Cloudflare Tunnel, nginx, ALB) so emitted URLs carry the correct scheme |
|
|
@@ -131,19 +130,6 @@ await createApp({
|
|
|
131
130
|
| `DEV_MCP_CLIENT_ID` | `devMcpClientId` | — | Dev-only: override client ID |
|
|
132
131
|
| `DEV_MCP_SCOPES` | `devMcpScopes` | — | Dev-only: comma-separated scope overrides |
|
|
133
132
|
|
|
134
|
-
#### OAuth proxy (optional sub-object)
|
|
135
|
-
|
|
136
|
-
Activated when `OAUTH_PROXY_AUTHORIZATION_URL` or `OAUTH_PROXY_TOKEN_URL` is set.
|
|
137
|
-
|
|
138
|
-
| Env Var | `AppConfig` field | Notes |
|
|
139
|
-
|:--------|:-----------------|:------|
|
|
140
|
-
| `OAUTH_PROXY_AUTHORIZATION_URL` | `oauthProxy.authorizationUrl` | Proxy authorization endpoint |
|
|
141
|
-
| `OAUTH_PROXY_TOKEN_URL` | `oauthProxy.tokenUrl` | Proxy token endpoint |
|
|
142
|
-
| `OAUTH_PROXY_REVOCATION_URL` | `oauthProxy.revocationUrl` | Optional |
|
|
143
|
-
| `OAUTH_PROXY_ISSUER_URL` | `oauthProxy.issuerUrl` | Optional |
|
|
144
|
-
| `OAUTH_PROXY_SERVICE_DOCUMENTATION_URL` | `oauthProxy.serviceDocumentationUrl` | Optional |
|
|
145
|
-
| `OAUTH_PROXY_DEFAULT_CLIENT_REDIRECT_URIS` | `oauthProxy.defaultClientRedirectUris` | Comma-separated list |
|
|
146
|
-
|
|
147
133
|
---
|
|
148
134
|
|
|
149
135
|
### Storage
|
|
@@ -174,13 +160,13 @@ Activated when `OAUTH_PROXY_AUTHORIZATION_URL` or `OAUTH_PROXY_TOKEN_URL` is set
|
|
|
174
160
|
|
|
175
161
|
#### Supabase (optional sub-object)
|
|
176
162
|
|
|
177
|
-
Activated when
|
|
163
|
+
Activated when `SUPABASE_URL` is set.
|
|
178
164
|
|
|
179
165
|
| Env Var | `AppConfig` field | Notes |
|
|
180
166
|
|:--------|:-----------------|:------|
|
|
181
167
|
| `SUPABASE_URL` | `supabase.url` | Required to activate |
|
|
182
|
-
| `
|
|
183
|
-
| `
|
|
168
|
+
| `SUPABASE_SERVICE_ROLE_KEY` | `supabase.serviceRoleKey` | Required by the `supabase` storage provider (admin client) |
|
|
169
|
+
| `SUPABASE_ANON_KEY` | `supabase.anonKey` | Optional; for the server's own public client — the framework never reads it |
|
|
184
170
|
|
|
185
171
|
---
|
|
186
172
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
McpError constructor, JsonRpcErrorCode reference, and error handling patterns for `@cyanheads/mcp-ts-core`. Use when looking up error codes, understanding where errors should be thrown vs. caught, or using ErrorHandler.tryCatch in services.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.10"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -363,6 +363,7 @@ Important properties:
|
|
|
363
363
|
- **`data` propagation is restricted** to explicitly-thrown `McpError.data` and `ZodError.issues`. Auto-classified plain errors (`TypeError`, network errors, etc.) emit `code` + `message` only — no `data` — so internal classification context never leaks to clients.
|
|
364
364
|
- **Recovery hint mirroring is automatic.** When the thrown `McpError` carries `data.recovery.hint`, the handler factory appends it to the `content[]` text so the markdown surface matches the JSON surface. Authors don't need to format the hint manually.
|
|
365
365
|
- **Argument-schema rejection is a tool error with the same envelope.** An unknown root key, a wrong type, a missing required field, or a failed constraint returns `isError: true` with `structuredContent.error.code = -32602` (`InvalidParams`) and the readable `Invalid arguments for tool <name>: …` diagnostic in `content[]`. The handler never runs. Two neighbouring failures keep the protocol error path instead, arriving as a JSON-RPC error rather than a tool result: an unknown or disabled tool name, and a malformed request envelope.
|
|
366
|
+
- **A schema constraint cannot carry a declared reason.** Because the handler never runs, a rejection by `.max()`, `.regex()`, `.min()`, or any other Zod refinement bypasses `errors[]` entirely: it arrives as `InvalidParams` with `data.issues` and no `data.reason`, so a caller has nothing to branch on and gets no recovery hint. Decide per constraint which surface it belongs on. A bound that is purely structural — the input is the wrong shape and no guidance beyond the diagnostic would help — belongs on the schema, where it also advertises itself in `inputSchema`. A bound a caller is expected to recover from belongs in the handler as `ctx.fail('reason', message, ctx.recoveryFor('reason'))` against a declared `errors[]` entry, with the limit restated in the field's `.describe()` so it is still visible before the call. Enforcing the same bound in both places is the trap: the schema wins, and the contract entry becomes unreachable while still reading as covered.
|
|
366
367
|
|
|
367
368
|
**Handler — throw freely, no try/catch:**
|
|
368
369
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Stand up a persistent, self-refreshing local mirror of a bulk upstream dataset with the MirrorService (@cyanheads/mcp-ts-core/mirror). Use when a server wraps a large or slow API and should query a synced local index (embedded SQLite + FTS5) instead of paginating the live API per request.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.2"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -81,6 +81,8 @@ Why they can't merge: during a from-scratch init the records aren't ordered by t
|
|
|
81
81
|
|
|
82
82
|
For access paths the generic query can't express — junction tables for index-backed multi-value filtering, denormalized counters, bespoke `bm25` weighting — use the **raw handle**: `const db = await mirror.raw();` then run prepared statements against your own auxiliary tables (declare them via a migration). Add the auxiliary DDL in a `migrations` step; maintain it from your `sync` mapping or SQL triggers.
|
|
83
83
|
|
|
84
|
+
A migration runs identically on first creation and on upgrade: a fresh database runs every migration up to `version` right after the declarative DDL, an existing one runs only those above its stored version. So `up()` must tolerate a database that already has the current declarative shape — `CREATE TABLE IF NOT EXISTS` for auxiliary objects, never an `ALTER` that assumes an older layout of a declared column.
|
|
85
|
+
|
|
84
86
|
## Readiness — key off the completion marker, not live status
|
|
85
87
|
|
|
86
88
|
`status().ready` is `true` once a full sync has **ever completed** (`completedAt != null`), not when `status === 'complete'`. The dataset stays transactionally queryable during a refresh, so a mirror mid-refresh — or one whose last refresh failed — is still ready and should keep serving. Gate the mirror read path on `await mirror.ready()`; fall back to the live API only when it is `false` (cold, never-completed init).
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
API reference for built-in service providers (LLM, Speech, Graph). Use when looking up service interfaces, provider capabilities, or integration patterns.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.5"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -24,7 +24,7 @@ The provider interface — implemented by ElevenLabs (TTS) and Whisper (STT):
|
|
|
24
24
|
| `.getSTTProvider()` | `ISpeechProvider` | Throws `McpError(InvalidRequest)` if no STT provider configured |
|
|
25
25
|
| `.hasTTS()` | `boolean` | Check if TTS is available |
|
|
26
26
|
| `.hasSTT()` | `boolean` | Check if STT is available |
|
|
27
|
-
| `.healthCheck()` | `Promise<{ tts: boolean; stt: boolean }>` | Checks both providers
|
|
27
|
+
| `.healthCheck()` | `Promise<{ tts: boolean; stt: boolean }>` | Checks both providers in parallel |
|
|
28
28
|
|
|
29
29
|
## Providers
|
|
30
30
|
|
|
@@ -52,7 +52,6 @@ const ttsProvider = speechService.getTTSProvider();
|
|
|
52
52
|
const ttsResult = await ttsProvider.textToSpeech({
|
|
53
53
|
text: 'Hello, world!',
|
|
54
54
|
voice: { voiceId: 'some-voice-id' },
|
|
55
|
-
format: 'mp3',
|
|
56
55
|
});
|
|
57
56
|
|
|
58
57
|
// Speech-to-Text
|