@collage-dam/mcp-server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +56 -0
- package/CHANGELOG.md +90 -0
- package/LICENSE +21 -0
- package/README.md +512 -0
- package/dist/client.d.ts +497 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +1162 -0
- package/dist/client.js.map +1 -0
- package/dist/conventions/confirmation.d.ts +89 -0
- package/dist/conventions/confirmation.d.ts.map +1 -0
- package/dist/conventions/confirmation.js +132 -0
- package/dist/conventions/confirmation.js.map +1 -0
- package/dist/conventions/dry-run/batch-executor.d.ts +36 -0
- package/dist/conventions/dry-run/batch-executor.d.ts.map +1 -0
- package/dist/conventions/dry-run/batch-executor.js +89 -0
- package/dist/conventions/dry-run/batch-executor.js.map +1 -0
- package/dist/conventions/dry-run/diff-renderer.d.ts +34 -0
- package/dist/conventions/dry-run/diff-renderer.d.ts.map +1 -0
- package/dist/conventions/dry-run/diff-renderer.js +158 -0
- package/dist/conventions/dry-run/diff-renderer.js.map +1 -0
- package/dist/conventions/dry-run/index.d.ts +13 -0
- package/dist/conventions/dry-run/index.d.ts.map +1 -0
- package/dist/conventions/dry-run/index.js +10 -0
- package/dist/conventions/dry-run/index.js.map +1 -0
- package/dist/conventions/dry-run/mutating-tool.d.ts +64 -0
- package/dist/conventions/dry-run/mutating-tool.d.ts.map +1 -0
- package/dist/conventions/dry-run/mutating-tool.js +88 -0
- package/dist/conventions/dry-run/mutating-tool.js.map +1 -0
- package/dist/conventions/dry-run/summary.d.ts +66 -0
- package/dist/conventions/dry-run/summary.d.ts.map +1 -0
- package/dist/conventions/dry-run/summary.js +185 -0
- package/dist/conventions/dry-run/summary.js.map +1 -0
- package/dist/conventions/dry-run/types.d.ts +597 -0
- package/dist/conventions/dry-run/types.d.ts.map +1 -0
- package/dist/conventions/dry-run/types.js +108 -0
- package/dist/conventions/dry-run/types.js.map +1 -0
- package/dist/conventions/dry-run/with-dry-run.d.ts +66 -0
- package/dist/conventions/dry-run/with-dry-run.d.ts.map +1 -0
- package/dist/conventions/dry-run/with-dry-run.js +219 -0
- package/dist/conventions/dry-run/with-dry-run.js.map +1 -0
- package/dist/conventions/env.d.ts +49 -0
- package/dist/conventions/env.d.ts.map +1 -0
- package/dist/conventions/env.js +84 -0
- package/dist/conventions/env.js.map +1 -0
- package/dist/conventions/errors.d.ts +68 -0
- package/dist/conventions/errors.d.ts.map +1 -0
- package/dist/conventions/errors.js +81 -0
- package/dist/conventions/errors.js.map +1 -0
- package/dist/conventions/logger.d.ts +28 -0
- package/dist/conventions/logger.d.ts.map +1 -0
- package/dist/conventions/logger.js +105 -0
- package/dist/conventions/logger.js.map +1 -0
- package/dist/conventions/pagination.d.ts +37 -0
- package/dist/conventions/pagination.d.ts.map +1 -0
- package/dist/conventions/pagination.js +53 -0
- package/dist/conventions/pagination.js.map +1 -0
- package/dist/conventions/rate-limiter.d.ts +54 -0
- package/dist/conventions/rate-limiter.d.ts.map +1 -0
- package/dist/conventions/rate-limiter.js +143 -0
- package/dist/conventions/rate-limiter.js.map +1 -0
- package/dist/conventions/response-budget.d.ts +66 -0
- package/dist/conventions/response-budget.d.ts.map +1 -0
- package/dist/conventions/response-budget.js +89 -0
- package/dist/conventions/response-budget.js.map +1 -0
- package/dist/conventions/schema-version.d.ts +27 -0
- package/dist/conventions/schema-version.d.ts.map +1 -0
- package/dist/conventions/schema-version.js +29 -0
- package/dist/conventions/schema-version.js.map +1 -0
- package/dist/conventions/state-store-redis.d.ts +32 -0
- package/dist/conventions/state-store-redis.d.ts.map +1 -0
- package/dist/conventions/state-store-redis.js +77 -0
- package/dist/conventions/state-store-redis.js.map +1 -0
- package/dist/conventions/state-store.d.ts +46 -0
- package/dist/conventions/state-store.d.ts.map +1 -0
- package/dist/conventions/state-store.js +105 -0
- package/dist/conventions/state-store.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +421 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/collection-audit.d.ts +13 -0
- package/dist/prompts/collection-audit.d.ts.map +1 -0
- package/dist/prompts/collection-audit.js +168 -0
- package/dist/prompts/collection-audit.js.map +1 -0
- package/dist/prompts/create-distribution.d.ts +15 -0
- package/dist/prompts/create-distribution.d.ts.map +1 -0
- package/dist/prompts/create-distribution.js +111 -0
- package/dist/prompts/create-distribution.js.map +1 -0
- package/dist/prompts/helpers.d.ts +20 -0
- package/dist/prompts/helpers.d.ts.map +1 -0
- package/dist/prompts/helpers.js +53 -0
- package/dist/prompts/helpers.js.map +1 -0
- package/dist/prompts/library-health-audit.d.ts +13 -0
- package/dist/prompts/library-health-audit.d.ts.map +1 -0
- package/dist/prompts/library-health-audit.js +131 -0
- package/dist/prompts/library-health-audit.js.map +1 -0
- package/dist/prompts/usage-insights.d.ts +13 -0
- package/dist/prompts/usage-insights.d.ts.map +1 -0
- package/dist/prompts/usage-insights.js +98 -0
- package/dist/prompts/usage-insights.js.map +1 -0
- package/dist/prompts/wrap-prompt-as-tool.d.ts +48 -0
- package/dist/prompts/wrap-prompt-as-tool.d.ts.map +1 -0
- package/dist/prompts/wrap-prompt-as-tool.js +61 -0
- package/dist/prompts/wrap-prompt-as-tool.js.map +1 -0
- package/dist/resources/asset-by-id.d.ts +4 -0
- package/dist/resources/asset-by-id.d.ts.map +1 -0
- package/dist/resources/asset-by-id.js +27 -0
- package/dist/resources/asset-by-id.js.map +1 -0
- package/dist/resources/collections.d.ts +5 -0
- package/dist/resources/collections.d.ts.map +1 -0
- package/dist/resources/collections.js +48 -0
- package/dist/resources/collections.js.map +1 -0
- package/dist/resources/custom-fields.d.ts +4 -0
- package/dist/resources/custom-fields.d.ts.map +1 -0
- package/dist/resources/custom-fields.js +30 -0
- package/dist/resources/custom-fields.js.map +1 -0
- package/dist/resources/folders.d.ts +5 -0
- package/dist/resources/folders.d.ts.map +1 -0
- package/dist/resources/folders.js +73 -0
- package/dist/resources/folders.js.map +1 -0
- package/dist/resources/helpers.d.ts +17 -0
- package/dist/resources/helpers.d.ts.map +1 -0
- package/dist/resources/helpers.js +59 -0
- package/dist/resources/helpers.js.map +1 -0
- package/dist/resources/portals.d.ts +5 -0
- package/dist/resources/portals.d.ts.map +1 -0
- package/dist/resources/portals.js +81 -0
- package/dist/resources/portals.js.map +1 -0
- package/dist/resources/recent-and-dashboard.d.ts +5 -0
- package/dist/resources/recent-and-dashboard.d.ts.map +1 -0
- package/dist/resources/recent-and-dashboard.js +42 -0
- package/dist/resources/recent-and-dashboard.js.map +1 -0
- package/dist/tools/asset-selection.d.ts +102 -0
- package/dist/tools/asset-selection.d.ts.map +1 -0
- package/dist/tools/asset-selection.js +133 -0
- package/dist/tools/asset-selection.js.map +1 -0
- package/dist/tools/audit/audit-folder-structure.d.ts +108 -0
- package/dist/tools/audit/audit-folder-structure.d.ts.map +1 -0
- package/dist/tools/audit/audit-folder-structure.js +260 -0
- package/dist/tools/audit/audit-folder-structure.js.map +1 -0
- package/dist/tools/audit/audit-naming-conventions.d.ts +83 -0
- package/dist/tools/audit/audit-naming-conventions.d.ts.map +1 -0
- package/dist/tools/audit/audit-naming-conventions.js +238 -0
- package/dist/tools/audit/audit-naming-conventions.js.map +1 -0
- package/dist/tools/audit/audit-tagging-hygiene.d.ts +77 -0
- package/dist/tools/audit/audit-tagging-hygiene.d.ts.map +1 -0
- package/dist/tools/audit/audit-tagging-hygiene.js +402 -0
- package/dist/tools/audit/audit-tagging-hygiene.js.map +1 -0
- package/dist/tools/audit/detect-duplicates.d.ts +62 -0
- package/dist/tools/audit/detect-duplicates.d.ts.map +1 -0
- package/dist/tools/audit/detect-duplicates.js +0 -0
- package/dist/tools/audit/detect-duplicates.js.map +1 -0
- package/dist/tools/audit/types.d.ts +526 -0
- package/dist/tools/audit/types.d.ts.map +1 -0
- package/dist/tools/audit/types.js +188 -0
- package/dist/tools/audit/types.js.map +1 -0
- package/dist/tools/bulk-move-assets.d.ts +78 -0
- package/dist/tools/bulk-move-assets.d.ts.map +1 -0
- package/dist/tools/bulk-move-assets.js +122 -0
- package/dist/tools/bulk-move-assets.js.map +1 -0
- package/dist/tools/bulk-normalize-filenames.d.ts +62 -0
- package/dist/tools/bulk-normalize-filenames.d.ts.map +1 -0
- package/dist/tools/bulk-normalize-filenames.js +237 -0
- package/dist/tools/bulk-normalize-filenames.js.map +1 -0
- package/dist/tools/bulk-rename-assets.d.ts +79 -0
- package/dist/tools/bulk-rename-assets.d.ts.map +1 -0
- package/dist/tools/bulk-rename-assets.js +139 -0
- package/dist/tools/bulk-rename-assets.js.map +1 -0
- package/dist/tools/bulk-tags.d.ts +107 -0
- package/dist/tools/bulk-tags.d.ts.map +1 -0
- package/dist/tools/bulk-tags.js +220 -0
- package/dist/tools/bulk-tags.js.map +1 -0
- package/dist/tools/client-adapters.d.ts +76 -0
- package/dist/tools/client-adapters.d.ts.map +1 -0
- package/dist/tools/client-adapters.js +648 -0
- package/dist/tools/client-adapters.js.map +1 -0
- package/dist/tools/collection-membership.d.ts +90 -0
- package/dist/tools/collection-membership.d.ts.map +1 -0
- package/dist/tools/collection-membership.js +195 -0
- package/dist/tools/collection-membership.js.map +1 -0
- package/dist/tools/create-collection.d.ts +63 -0
- package/dist/tools/create-collection.d.ts.map +1 -0
- package/dist/tools/create-collection.js +151 -0
- package/dist/tools/create-collection.js.map +1 -0
- package/dist/tools/create-folder.d.ts +46 -0
- package/dist/tools/create-folder.d.ts.map +1 -0
- package/dist/tools/create-folder.js +83 -0
- package/dist/tools/create-folder.js.map +1 -0
- package/dist/tools/create-share-link.d.ts +107 -0
- package/dist/tools/create-share-link.d.ts.map +1 -0
- package/dist/tools/create-share-link.js +239 -0
- package/dist/tools/create-share-link.js.map +1 -0
- package/dist/tools/get-asset-details.d.ts +401 -0
- package/dist/tools/get-asset-details.d.ts.map +1 -0
- package/dist/tools/get-asset-details.js +56 -0
- package/dist/tools/get-asset-details.js.map +1 -0
- package/dist/tools/get-collection.d.ts +126 -0
- package/dist/tools/get-collection.d.ts.map +1 -0
- package/dist/tools/get-collection.js +52 -0
- package/dist/tools/get-collection.js.map +1 -0
- package/dist/tools/get-embed-code.d.ts +195 -0
- package/dist/tools/get-embed-code.d.ts.map +1 -0
- package/dist/tools/get-embed-code.js +214 -0
- package/dist/tools/get-embed-code.js.map +1 -0
- package/dist/tools/insights/analyze-share-links.d.ts +159 -0
- package/dist/tools/insights/analyze-share-links.d.ts.map +1 -0
- package/dist/tools/insights/analyze-share-links.js +314 -0
- package/dist/tools/insights/analyze-share-links.js.map +1 -0
- package/dist/tools/insights/insight-cache.d.ts +36 -0
- package/dist/tools/insights/insight-cache.d.ts.map +1 -0
- package/dist/tools/insights/insight-cache.js +98 -0
- package/dist/tools/insights/insight-cache.js.map +1 -0
- package/dist/tools/insights/report-asset-activation.d.ts +149 -0
- package/dist/tools/insights/report-asset-activation.d.ts.map +1 -0
- package/dist/tools/insights/report-asset-activation.js +380 -0
- package/dist/tools/insights/report-asset-activation.js.map +1 -0
- package/dist/tools/insights/report-stale-assets.d.ts +120 -0
- package/dist/tools/insights/report-stale-assets.d.ts.map +1 -0
- package/dist/tools/insights/report-stale-assets.js +281 -0
- package/dist/tools/insights/report-stale-assets.js.map +1 -0
- package/dist/tools/insights/report-top-assets.d.ts +139 -0
- package/dist/tools/insights/report-top-assets.d.ts.map +1 -0
- package/dist/tools/insights/report-top-assets.js +407 -0
- package/dist/tools/insights/report-top-assets.js.map +1 -0
- package/dist/tools/list-categories.d.ts +127 -0
- package/dist/tools/list-categories.d.ts.map +1 -0
- package/dist/tools/list-categories.js +68 -0
- package/dist/tools/list-categories.js.map +1 -0
- package/dist/tools/list-collections.d.ts +127 -0
- package/dist/tools/list-collections.d.ts.map +1 -0
- package/dist/tools/list-collections.js +53 -0
- package/dist/tools/list-collections.js.map +1 -0
- package/dist/tools/list-custom-fields.d.ts +125 -0
- package/dist/tools/list-custom-fields.d.ts.map +1 -0
- package/dist/tools/list-custom-fields.js +51 -0
- package/dist/tools/list-custom-fields.js.map +1 -0
- package/dist/tools/list-share-links.d.ts +192 -0
- package/dist/tools/list-share-links.d.ts.map +1 -0
- package/dist/tools/list-share-links.js +92 -0
- package/dist/tools/list-share-links.js.map +1 -0
- package/dist/tools/list-workspaces.d.ts +88 -0
- package/dist/tools/list-workspaces.d.ts.map +1 -0
- package/dist/tools/list-workspaces.js +71 -0
- package/dist/tools/list-workspaces.js.map +1 -0
- package/dist/tools/move-asset.d.ts +48 -0
- package/dist/tools/move-asset.d.ts.map +1 -0
- package/dist/tools/move-asset.js +85 -0
- package/dist/tools/move-asset.js.map +1 -0
- package/dist/tools/rename-asset.d.ts +88 -0
- package/dist/tools/rename-asset.d.ts.map +1 -0
- package/dist/tools/rename-asset.js +100 -0
- package/dist/tools/rename-asset.js.map +1 -0
- package/dist/tools/rename-folder.d.ts +55 -0
- package/dist/tools/rename-folder.d.ts.map +1 -0
- package/dist/tools/rename-folder.js +101 -0
- package/dist/tools/rename-folder.js.map +1 -0
- package/dist/tools/revoke-share-link.d.ts +55 -0
- package/dist/tools/revoke-share-link.d.ts.map +1 -0
- package/dist/tools/revoke-share-link.js +77 -0
- package/dist/tools/revoke-share-link.js.map +1 -0
- package/dist/tools/search/facets.d.ts +34 -0
- package/dist/tools/search/facets.d.ts.map +1 -0
- package/dist/tools/search/facets.js +147 -0
- package/dist/tools/search/facets.js.map +1 -0
- package/dist/tools/search/filter-builder.d.ts +33 -0
- package/dist/tools/search/filter-builder.d.ts.map +1 -0
- package/dist/tools/search/filter-builder.js +111 -0
- package/dist/tools/search/filter-builder.js.map +1 -0
- package/dist/tools/search/search-assets.d.ts +41 -0
- package/dist/tools/search/search-assets.d.ts.map +1 -0
- package/dist/tools/search/search-assets.js +162 -0
- package/dist/tools/search/search-assets.js.map +1 -0
- package/dist/tools/search/search-collections.d.ts +35 -0
- package/dist/tools/search/search-collections.d.ts.map +1 -0
- package/dist/tools/search/search-collections.js +103 -0
- package/dist/tools/search/search-collections.js.map +1 -0
- package/dist/tools/search/types.d.ts +1047 -0
- package/dist/tools/search/types.d.ts.map +1 -0
- package/dist/tools/search/types.js +216 -0
- package/dist/tools/search/types.js.map +1 -0
- package/dist/tools/update-asset-metadata.d.ts +78 -0
- package/dist/tools/update-asset-metadata.d.ts.map +1 -0
- package/dist/tools/update-asset-metadata.js +203 -0
- package/dist/tools/update-asset-metadata.js.map +1 -0
- package/dist/tools/update-collection.d.ts +69 -0
- package/dist/tools/update-collection.d.ts.map +1 -0
- package/dist/tools/update-collection.js +142 -0
- package/dist/tools/update-collection.js.map +1 -0
- package/dist/tools/view-category-contents.d.ts +231 -0
- package/dist/tools/view-category-contents.d.ts.map +1 -0
- package/dist/tools/view-category-contents.js +97 -0
- package/dist/tools/view-category-contents.js.map +1 -0
- package/dist/types.d.ts +1326 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +288 -0
- package/dist/types.js.map +1 -0
- package/dist/typesense.d.ts +84 -0
- package/dist/typesense.d.ts.map +1 -0
- package/dist/typesense.js +243 -0
- package/dist/typesense.js.map +1 -0
- package/docs/api-field-verification.md +244 -0
- package/docs/deployment-runbook.md +446 -0
- package/docs/security-review.md +195 -0
- package/docs/typesense-filter-schema.md +262 -0
- package/docs/verified-endpoints.md +38 -0
- package/package.json +72 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Constants
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
/** Soft-warn threshold — log a warning when a single tool response exceeds this. */
|
|
6
|
+
export const SOFT_WARN_TOKENS = 4_000;
|
|
7
|
+
/** Hard cap — automatically truncate responses that exceed this. */
|
|
8
|
+
export const HARD_CAP_TOKENS = 12_000;
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Token estimation
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* Rough token-count heuristic for English text.
|
|
14
|
+
*
|
|
15
|
+
* cl100k_base averages ~4 characters per token for typical English /
|
|
16
|
+
* JSON-serialised content. This avoids pulling in the full tiktoken
|
|
17
|
+
* dependency while remaining "good enough" for budget enforcement.
|
|
18
|
+
*/
|
|
19
|
+
export function estimateTokens(text) {
|
|
20
|
+
return Math.ceil(text.length / 4);
|
|
21
|
+
}
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Response budget result schema & type
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
/**
|
|
26
|
+
* Zod schema factory for a budget-wrapped response.
|
|
27
|
+
*
|
|
28
|
+
* Usage:
|
|
29
|
+
* const schema = responseBudgetResultSchema(z.array(myItemSchema));
|
|
30
|
+
*/
|
|
31
|
+
export function responseBudgetResultSchema(dataSchema) {
|
|
32
|
+
return z.object({
|
|
33
|
+
data: dataSchema,
|
|
34
|
+
token_estimate: z.number().int().nonnegative(),
|
|
35
|
+
truncated: z.boolean(),
|
|
36
|
+
next_cursor: z.string().nullable().optional(),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Walk through `items`, accumulating estimated tokens. If the running
|
|
41
|
+
* total would exceed {@link HARD_CAP_TOKENS}, stop early, mark the
|
|
42
|
+
* response as truncated, and attach a `next_cursor` so the caller can
|
|
43
|
+
* resume.
|
|
44
|
+
*/
|
|
45
|
+
export function applyResponseBudget(items, opts) {
|
|
46
|
+
const { serialize, offset } = opts;
|
|
47
|
+
const accepted = [];
|
|
48
|
+
let cumulativeTokens = 0;
|
|
49
|
+
for (let i = 0; i < items.length; i++) {
|
|
50
|
+
const serialised = serialize(items[i]);
|
|
51
|
+
const itemTokens = estimateTokens(serialised);
|
|
52
|
+
if (cumulativeTokens + itemTokens > HARD_CAP_TOKENS && accepted.length > 0) {
|
|
53
|
+
// Would exceed the hard cap — stop here.
|
|
54
|
+
return {
|
|
55
|
+
data: accepted,
|
|
56
|
+
token_estimate: cumulativeTokens,
|
|
57
|
+
truncated: true,
|
|
58
|
+
next_cursor: String(offset + accepted.length),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// Always include at least one item even if it alone exceeds the cap,
|
|
62
|
+
// so clients never receive an empty page.
|
|
63
|
+
accepted.push(items[i]);
|
|
64
|
+
cumulativeTokens += itemTokens;
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
data: accepted,
|
|
68
|
+
token_estimate: cumulativeTokens,
|
|
69
|
+
truncated: false,
|
|
70
|
+
next_cursor: null,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Soft-warn helper
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
/**
|
|
77
|
+
* Log a warning to stderr when a response exceeds {@link SOFT_WARN_TOKENS}.
|
|
78
|
+
*
|
|
79
|
+
* This intentionally writes to `process.stderr` so it stays out of MCP
|
|
80
|
+
* stdout transport. Will be replaced with pino once the shared logger
|
|
81
|
+
* convention lands.
|
|
82
|
+
*/
|
|
83
|
+
export function warnIfOverBudget(tokenEstimate, toolName) {
|
|
84
|
+
if (tokenEstimate > SOFT_WARN_TOKENS) {
|
|
85
|
+
process.stderr.write(`[response-budget] WARNING: "${toolName}" response ~${tokenEstimate} tokens ` +
|
|
86
|
+
`(soft limit ${SOFT_WARN_TOKENS})\n`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=response-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-budget.js","sourceRoot":"","sources":["../../src/conventions/response-budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,oFAAoF;AACpF,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAEtC,oEAAoE;AACpE,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;AAEtC,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,8EAA8E;AAC9E,uCAAuC;AACvC,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CAAyB,UAAa;IAC9E,OAAO,CAAC,CAAC,MAAM,CAAC;QACd,IAAI,EAAE,UAAU;QAChB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;QAC9C,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;QACtB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;KAC9C,CAAC,CAAC;AACL,CAAC;AAuBD;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAU,EACV,IAAgC;IAEhC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAEnC,MAAM,QAAQ,GAAQ,EAAE,CAAC;IACzB,IAAI,gBAAgB,GAAG,CAAC,CAAC;IAEzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAM,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;QAE9C,IAAI,gBAAgB,GAAG,UAAU,GAAG,eAAe,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3E,yCAAyC;YACzC,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,cAAc,EAAE,gBAAgB;gBAChC,SAAS,EAAE,IAAI;gBACf,WAAW,EAAE,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;aAC9C,CAAC;QACJ,CAAC;QAED,qEAAqE;QACrE,0CAA0C;QAC1C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAM,CAAC,CAAC;QAC7B,gBAAgB,IAAI,UAAU,CAAC;IACjC,CAAC;IAED,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,cAAc,EAAE,gBAAgB;QAChC,SAAS,EAAE,KAAK;QAChB,WAAW,EAAE,IAAI;KAClB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,aAAqB,EAAE,QAAgB;IACtE,IAAI,aAAa,GAAG,gBAAgB,EAAE,CAAC;QACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+BAA+B,QAAQ,eAAe,aAAa,UAAU;YAC3E,eAAe,gBAAgB,KAAK,CACvC,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Single source of truth for the MCP schema version.
|
|
4
|
+
* Every tool response includes this as a top-level `schema_version` field.
|
|
5
|
+
*
|
|
6
|
+
* Versioning policy:
|
|
7
|
+
* - MVP ships at 0.1.x with no compatibility guarantees until 1.0.0
|
|
8
|
+
* - Breaking changes to any tool shape bump the major version
|
|
9
|
+
* - Additive changes bump the minor version
|
|
10
|
+
*/
|
|
11
|
+
export declare const COLLAGE_MCP_SCHEMA_VERSION = "0.1.0";
|
|
12
|
+
/**
|
|
13
|
+
* Zod literal schema matching the current schema version.
|
|
14
|
+
* Use in tool response schemas to enforce the exact version string.
|
|
15
|
+
*/
|
|
16
|
+
export declare const SchemaVersionSchema: z.ZodLiteral<"0.1.0">;
|
|
17
|
+
/**
|
|
18
|
+
* Stamps a tool response object with the current schema version.
|
|
19
|
+
*/
|
|
20
|
+
export declare function addSchemaVersion<T extends Record<string, unknown>>(response: T): T & {
|
|
21
|
+
schema_version: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Checks whether a version string matches the current schema version constant.
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateSchemaVersion(version: string): boolean;
|
|
27
|
+
//# sourceMappingURL=schema-version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-version.d.ts","sourceRoot":"","sources":["../../src/conventions/schema-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,UAAU,CAAC;AAElD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,uBAAwC,CAAC;AAEzE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,QAAQ,EAAE,CAAC,GACV,CAAC,GAAG;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,CAEhC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE9D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Single source of truth for the MCP schema version.
|
|
4
|
+
* Every tool response includes this as a top-level `schema_version` field.
|
|
5
|
+
*
|
|
6
|
+
* Versioning policy:
|
|
7
|
+
* - MVP ships at 0.1.x with no compatibility guarantees until 1.0.0
|
|
8
|
+
* - Breaking changes to any tool shape bump the major version
|
|
9
|
+
* - Additive changes bump the minor version
|
|
10
|
+
*/
|
|
11
|
+
export const COLLAGE_MCP_SCHEMA_VERSION = '0.1.0';
|
|
12
|
+
/**
|
|
13
|
+
* Zod literal schema matching the current schema version.
|
|
14
|
+
* Use in tool response schemas to enforce the exact version string.
|
|
15
|
+
*/
|
|
16
|
+
export const SchemaVersionSchema = z.literal(COLLAGE_MCP_SCHEMA_VERSION);
|
|
17
|
+
/**
|
|
18
|
+
* Stamps a tool response object with the current schema version.
|
|
19
|
+
*/
|
|
20
|
+
export function addSchemaVersion(response) {
|
|
21
|
+
return { ...response, schema_version: COLLAGE_MCP_SCHEMA_VERSION };
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Checks whether a version string matches the current schema version constant.
|
|
25
|
+
*/
|
|
26
|
+
export function validateSchemaVersion(version) {
|
|
27
|
+
return version === COLLAGE_MCP_SCHEMA_VERSION;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=schema-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-version.js","sourceRoot":"","sources":["../../src/conventions/schema-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,OAAO,CAAC;AAElD;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;AAEzE;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAW;IAEX,OAAO,EAAE,GAAG,QAAQ,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,OAAO,OAAO,KAAK,0BAA0B,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Redis } from 'ioredis';
|
|
2
|
+
import type { EphemeralStateStore } from './state-store.js';
|
|
3
|
+
export interface RedisStateStoreOptions {
|
|
4
|
+
redis: Redis;
|
|
5
|
+
prefix?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Redis-backed implementation of `EphemeralStateStore`.
|
|
9
|
+
*
|
|
10
|
+
* Values are JSON-serialised before storage and deserialised on read.
|
|
11
|
+
* Keys are namespaced with a configurable prefix (default `collage-mcp:`).
|
|
12
|
+
* TTL is delegated to Redis via `SET … EX`.
|
|
13
|
+
*/
|
|
14
|
+
export declare class RedisStateStore<T> implements EphemeralStateStore<T> {
|
|
15
|
+
private readonly redis;
|
|
16
|
+
private readonly prefix;
|
|
17
|
+
constructor(options: RedisStateStoreOptions);
|
|
18
|
+
get(key: string): Promise<T | undefined>;
|
|
19
|
+
set(key: string, value: T, ttlMs?: number): Promise<void>;
|
|
20
|
+
delete(key: string): Promise<boolean>;
|
|
21
|
+
getAndDelete(key: string): Promise<T | undefined>;
|
|
22
|
+
has(key: string): Promise<boolean>;
|
|
23
|
+
private prefixed;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a `RedisStateStore` from a Redis connection URL.
|
|
27
|
+
*
|
|
28
|
+
* The returned store owns the `Redis` instance; callers should call
|
|
29
|
+
* `redis.quit()` when shutting down.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createRedisStateStore<T>(redisUrl: string, prefix?: string): RedisStateStore<T>;
|
|
32
|
+
//# sourceMappingURL=state-store-redis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-store-redis.d.ts","sourceRoot":"","sources":["../../src/conventions/state-store-redis.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAQ5D,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,qBAAa,eAAe,CAAC,CAAC,CAAE,YAAW,mBAAmB,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,EAAE,sBAAsB;IAKrC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAQxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAE,MAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKrC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAsBjD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOxC,OAAO,CAAC,QAAQ;CAGjB;AAID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GACd,eAAe,CAAC,CAAC,CAAC,CAGpB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// ── Redis State Store ────────────────────────────────────────────────
|
|
2
|
+
// Redis-backed adapter for EphemeralStateStore, used by the self-hosted
|
|
3
|
+
// HTTP transport. Values are JSON-serialized; all keys are prefixed.
|
|
4
|
+
import { Redis } from 'ioredis';
|
|
5
|
+
import { DEFAULT_TTL_MS } from './state-store.js';
|
|
6
|
+
// ── Constants ────────────────────────────────────────────────────────
|
|
7
|
+
const DEFAULT_PREFIX = 'collage-mcp:';
|
|
8
|
+
/**
|
|
9
|
+
* Redis-backed implementation of `EphemeralStateStore`.
|
|
10
|
+
*
|
|
11
|
+
* Values are JSON-serialised before storage and deserialised on read.
|
|
12
|
+
* Keys are namespaced with a configurable prefix (default `collage-mcp:`).
|
|
13
|
+
* TTL is delegated to Redis via `SET … EX`.
|
|
14
|
+
*/
|
|
15
|
+
export class RedisStateStore {
|
|
16
|
+
redis;
|
|
17
|
+
prefix;
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.redis = options.redis;
|
|
20
|
+
this.prefix = options.prefix ?? DEFAULT_PREFIX;
|
|
21
|
+
}
|
|
22
|
+
async get(key) {
|
|
23
|
+
const raw = await this.redis.get(this.prefixed(key));
|
|
24
|
+
if (raw === null) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return JSON.parse(raw);
|
|
28
|
+
}
|
|
29
|
+
async set(key, value, ttlMs = DEFAULT_TTL_MS) {
|
|
30
|
+
const serialised = JSON.stringify(value);
|
|
31
|
+
const ttlSeconds = Math.ceil(ttlMs / 1000);
|
|
32
|
+
await this.redis.set(this.prefixed(key), serialised, 'EX', ttlSeconds);
|
|
33
|
+
}
|
|
34
|
+
async delete(key) {
|
|
35
|
+
const count = await this.redis.del(this.prefixed(key));
|
|
36
|
+
return count > 0;
|
|
37
|
+
}
|
|
38
|
+
async getAndDelete(key) {
|
|
39
|
+
const prefixedKey = this.prefixed(key);
|
|
40
|
+
const pipeline = this.redis.multi();
|
|
41
|
+
pipeline.get(prefixedKey);
|
|
42
|
+
pipeline.del(prefixedKey);
|
|
43
|
+
const results = await pipeline.exec();
|
|
44
|
+
if (results === null) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
// results[0] is [error, value] for the GET command
|
|
48
|
+
const [getError, raw] = results[0];
|
|
49
|
+
if (getError !== null) {
|
|
50
|
+
throw getError;
|
|
51
|
+
}
|
|
52
|
+
if (raw === null) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
return JSON.parse(raw);
|
|
56
|
+
}
|
|
57
|
+
async has(key) {
|
|
58
|
+
const count = await this.redis.exists(this.prefixed(key));
|
|
59
|
+
return count > 0;
|
|
60
|
+
}
|
|
61
|
+
// ── Private ──────────────────────────────────────────────────────
|
|
62
|
+
prefixed(key) {
|
|
63
|
+
return `${this.prefix}${key}`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// ── Factory ──────────────────────────────────────────────────────────
|
|
67
|
+
/**
|
|
68
|
+
* Create a `RedisStateStore` from a Redis connection URL.
|
|
69
|
+
*
|
|
70
|
+
* The returned store owns the `Redis` instance; callers should call
|
|
71
|
+
* `redis.quit()` when shutting down.
|
|
72
|
+
*/
|
|
73
|
+
export function createRedisStateStore(redisUrl, prefix) {
|
|
74
|
+
const redis = new Redis(redisUrl);
|
|
75
|
+
return new RedisStateStore({ redis, prefix });
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=state-store-redis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-store-redis.js","sourceRoot":"","sources":["../../src/conventions/state-store-redis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Default time-to-live for state entries: 5 minutes. */
|
|
2
|
+
export declare const DEFAULT_TTL_MS = 300000;
|
|
3
|
+
/** Interval for evicting expired entries: 60 seconds. */
|
|
4
|
+
export declare const CLEANUP_INTERVAL_MS = 60000;
|
|
5
|
+
/**
|
|
6
|
+
* A backend-agnostic contract for ephemeral key-value storage.
|
|
7
|
+
* Callers depend on this interface only; adapters implement it.
|
|
8
|
+
*/
|
|
9
|
+
export interface EphemeralStateStore<T> {
|
|
10
|
+
/** Retrieve a value by key. Returns `undefined` if missing or expired. */
|
|
11
|
+
get(key: string): Promise<T | undefined>;
|
|
12
|
+
/** Store a value with an optional TTL (defaults to `DEFAULT_TTL_MS`). */
|
|
13
|
+
set(key: string, value: T, ttlMs?: number): Promise<void>;
|
|
14
|
+
/** Delete a key. Returns `true` if the key existed and was removed. */
|
|
15
|
+
delete(key: string): Promise<boolean>;
|
|
16
|
+
/** Atomically retrieve and delete a value. Used by the execute step. */
|
|
17
|
+
getAndDelete(key: string): Promise<T | undefined>;
|
|
18
|
+
/** Check whether a non-expired entry exists for the key. */
|
|
19
|
+
has(key: string): Promise<boolean>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* In-memory implementation of `EphemeralStateStore`.
|
|
23
|
+
*
|
|
24
|
+
* Backed by a `Map` keyed by confirmation ID. Entries are evicted
|
|
25
|
+
* on access if expired, and a periodic cleanup sweep runs every
|
|
26
|
+
* `CLEANUP_INTERVAL_MS`. The cleanup interval is `unref()`'d so
|
|
27
|
+
* it does not keep the Node.js process alive.
|
|
28
|
+
*/
|
|
29
|
+
export declare class InMemoryStateStore<T> implements EphemeralStateStore<T> {
|
|
30
|
+
private readonly store;
|
|
31
|
+
private readonly cleanupTimer;
|
|
32
|
+
constructor();
|
|
33
|
+
get(key: string): Promise<T | undefined>;
|
|
34
|
+
set(key: string, value: T, ttlMs?: number): Promise<void>;
|
|
35
|
+
delete(key: string): Promise<boolean>;
|
|
36
|
+
getAndDelete(key: string): Promise<T | undefined>;
|
|
37
|
+
has(key: string): Promise<boolean>;
|
|
38
|
+
/** Returns the count of non-expired entries. */
|
|
39
|
+
get size(): number;
|
|
40
|
+
/** Remove all entries and stop the cleanup timer. */
|
|
41
|
+
clear(): void;
|
|
42
|
+
/** Stop the background cleanup interval. */
|
|
43
|
+
destroy(): void;
|
|
44
|
+
private evictExpired;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=state-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../../src/conventions/state-store.ts"],"names":[],"mappings":"AAOA,yDAAyD;AACzD,eAAO,MAAM,cAAc,SAAU,CAAC;AAEtC,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAI1C;;;GAGG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,0EAA0E;IAC1E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAEzC,yEAAyE;IACzE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1D,uEAAuE;IACvE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtC,wEAAwE;IACxE,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAElD,4DAA4D;IAC5D,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpC;AASD;;;;;;;GAOG;AACH,qBAAa,kBAAkB,CAAC,CAAC,CAAE,YAAW,mBAAmB,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;;IAaxD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAYxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAE,MAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAOzE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAYjD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYxC,gDAAgD;IAChD,IAAI,IAAI,IAAI,MAAM,CAWjB;IAED,qDAAqD;IACrD,KAAK,IAAI,IAAI;IAIb,4CAA4C;IAC5C,OAAO,IAAI,IAAI;IAOf,OAAO,CAAC,YAAY;CAQrB"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// ── Ephemeral State Store ────────────────────────────────────────────
|
|
2
|
+
// Backend-agnostic ephemeral state store interface and in-memory adapter.
|
|
3
|
+
// Used by the dry-run framework to store confirmation tokens.
|
|
4
|
+
// No external dependencies; stdio transport uses the in-memory adapter.
|
|
5
|
+
// ── Constants ────────────────────────────────────────────────────────
|
|
6
|
+
/** Default time-to-live for state entries: 5 minutes. */
|
|
7
|
+
export const DEFAULT_TTL_MS = 300_000;
|
|
8
|
+
/** Interval for evicting expired entries: 60 seconds. */
|
|
9
|
+
export const CLEANUP_INTERVAL_MS = 60_000;
|
|
10
|
+
/**
|
|
11
|
+
* In-memory implementation of `EphemeralStateStore`.
|
|
12
|
+
*
|
|
13
|
+
* Backed by a `Map` keyed by confirmation ID. Entries are evicted
|
|
14
|
+
* on access if expired, and a periodic cleanup sweep runs every
|
|
15
|
+
* `CLEANUP_INTERVAL_MS`. The cleanup interval is `unref()`'d so
|
|
16
|
+
* it does not keep the Node.js process alive.
|
|
17
|
+
*/
|
|
18
|
+
export class InMemoryStateStore {
|
|
19
|
+
store = new Map();
|
|
20
|
+
cleanupTimer;
|
|
21
|
+
constructor() {
|
|
22
|
+
this.cleanupTimer = setInterval(() => {
|
|
23
|
+
this.evictExpired();
|
|
24
|
+
}, CLEANUP_INTERVAL_MS);
|
|
25
|
+
// Ensure the timer doesn't prevent process exit
|
|
26
|
+
if (typeof this.cleanupTimer === 'object' && 'unref' in this.cleanupTimer) {
|
|
27
|
+
this.cleanupTimer.unref();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async get(key) {
|
|
31
|
+
const entry = this.store.get(key);
|
|
32
|
+
if (entry === undefined) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
if (Date.now() >= entry.expiresAt) {
|
|
36
|
+
this.store.delete(key);
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
return entry.value;
|
|
40
|
+
}
|
|
41
|
+
async set(key, value, ttlMs = DEFAULT_TTL_MS) {
|
|
42
|
+
this.store.set(key, {
|
|
43
|
+
value,
|
|
44
|
+
expiresAt: Date.now() + ttlMs,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
async delete(key) {
|
|
48
|
+
return this.store.delete(key);
|
|
49
|
+
}
|
|
50
|
+
async getAndDelete(key) {
|
|
51
|
+
const entry = this.store.get(key);
|
|
52
|
+
if (entry === undefined) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
this.store.delete(key);
|
|
56
|
+
if (Date.now() >= entry.expiresAt) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
return entry.value;
|
|
60
|
+
}
|
|
61
|
+
async has(key) {
|
|
62
|
+
const entry = this.store.get(key);
|
|
63
|
+
if (entry === undefined) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (Date.now() >= entry.expiresAt) {
|
|
67
|
+
this.store.delete(key);
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
/** Returns the count of non-expired entries. */
|
|
73
|
+
get size() {
|
|
74
|
+
let count = 0;
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
for (const [key, entry] of this.store) {
|
|
77
|
+
if (now >= entry.expiresAt) {
|
|
78
|
+
this.store.delete(key);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
count++;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return count;
|
|
85
|
+
}
|
|
86
|
+
/** Remove all entries and stop the cleanup timer. */
|
|
87
|
+
clear() {
|
|
88
|
+
this.store.clear();
|
|
89
|
+
}
|
|
90
|
+
/** Stop the background cleanup interval. */
|
|
91
|
+
destroy() {
|
|
92
|
+
clearInterval(this.cleanupTimer);
|
|
93
|
+
this.store.clear();
|
|
94
|
+
}
|
|
95
|
+
// ── Private ──────────────────────────────────────────────────────
|
|
96
|
+
evictExpired() {
|
|
97
|
+
const now = Date.now();
|
|
98
|
+
for (const [key, entry] of this.store) {
|
|
99
|
+
if (now >= entry.expiresAt) {
|
|
100
|
+
this.store.delete(key);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=state-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-store.js","sourceRoot":"","sources":["../../src/conventions/state-store.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
export { COLLAGE_MCP_SCHEMA_VERSION, SchemaVersionSchema, addSchemaVersion, validateSchemaVersion, } from './conventions/schema-version.js';
|
|
4
|
+
export declare function createServer(): Promise<McpServer>;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AA4OtF,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AAoCzC,wBAAsB,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC,CAylBvD"}
|