@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,262 @@
|
|
|
1
|
+
# Typesense Filter Schema (reverse-engineered)
|
|
2
|
+
|
|
3
|
+
This document captures the filter, query, sort, and result shapes that
|
|
4
|
+
Collage's Admin-Frontend issues against its Typesense Cloud cluster. The
|
|
5
|
+
MCP `search_assets` and `search_collections` tools mirror this contract
|
|
6
|
+
verbatim. **There is no upstream documentation** — every clause below
|
|
7
|
+
was reverse-engineered from live frontend code. As field names or
|
|
8
|
+
operators drift, the contract test harness in `tests/contract/` is the
|
|
9
|
+
tripwire.
|
|
10
|
+
|
|
11
|
+
Source files cited inline use repo-relative paths against the cloned
|
|
12
|
+
Admin-Frontend tree at `/Users/justin/Sites/southleft/collage/Admin-Frontend/`.
|
|
13
|
+
|
|
14
|
+
## Collections
|
|
15
|
+
|
|
16
|
+
Three Typesense collections are searchable:
|
|
17
|
+
|
|
18
|
+
| Collection | Domain |
|
|
19
|
+
| ----------------------------- | ------------------------------- |
|
|
20
|
+
| `digital_assets` | Asset rows (file metadata) |
|
|
21
|
+
| `dam_collections` | Curated asset collections |
|
|
22
|
+
| `digital_assets_categories` | Folders (the category tree) |
|
|
23
|
+
|
|
24
|
+
Reference: `Admin-Frontend/mixins/search-common-functions.js:355-395`.
|
|
25
|
+
|
|
26
|
+
## Workspace scoping (mandatory)
|
|
27
|
+
|
|
28
|
+
Every query is rewritten upstream to append the workspace clause:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
filter = filter.length
|
|
32
|
+
? `${filter} && workspace_id: ${workspace_unique_id}`
|
|
33
|
+
: `workspace_id: ${workspace_unique_id}`
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Source: `Admin-Frontend/api/typesense.js:212-215` (also lines 420-422
|
|
37
|
+
on the `search-ids` route). On the MCP side this is enforced at the
|
|
38
|
+
`searchWorkspaceScoped` wrapper in `src/typesense.ts` — tool authors
|
|
39
|
+
cannot omit it by construction.
|
|
40
|
+
|
|
41
|
+
## Common search params
|
|
42
|
+
|
|
43
|
+
From `Admin-Frontend/api/typesense.js:252-269`:
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
{
|
|
47
|
+
q: adjustedQuery, // q.toLowerCase() unless '*'
|
|
48
|
+
filter_by: filter,
|
|
49
|
+
sort_by: collectionSortBy,
|
|
50
|
+
infix: 'always', // substring matching enabled
|
|
51
|
+
prefix: true,
|
|
52
|
+
num_typos: 2,
|
|
53
|
+
typo_tokens_threshold: 1,
|
|
54
|
+
// optional: include_fields, group_by, group_limit, ...
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`commonSearchParams.query_by` defaults to `'search_name'` on the
|
|
59
|
+
results page (`pages/_workspace_id/dam/search.vue:1418`) and the
|
|
60
|
+
search bar (`components/dam/SearchBarTypeSense.vue:898`). The MCP
|
|
61
|
+
contract widens this to `display_file_name,search_name,description,tags,custom_fields`
|
|
62
|
+
to match the spec's stated query target set.
|
|
63
|
+
|
|
64
|
+
## Sort schema
|
|
65
|
+
|
|
66
|
+
`sort_by` is a comma-separated list of `field:direction` pairs, where
|
|
67
|
+
direction is `asc` or `desc`. Validation regex (server-side):
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
/^[a-zA-Z0-9_]+:(asc|desc)$/
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Source: `Admin-Frontend/api/typesense.js:160-189`.
|
|
74
|
+
|
|
75
|
+
Default sort:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
_text_match:desc,modified_at:desc
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Source: `pages/_workspace_id/dam/search.vue:1442` and
|
|
82
|
+
`components/dam/SearchBarTypeSense.vue:902`.
|
|
83
|
+
|
|
84
|
+
`sort_by` may also be a per-collection object — keys are collection
|
|
85
|
+
names, values are sort strings. For `dam_collections` and
|
|
86
|
+
`digital_assets_categories`, the upstream remaps `display_file_name:`
|
|
87
|
+
to `collection_name:` / `folder_name:` and falls back to
|
|
88
|
+
`modified_at:` when sorting by `file_size:` or `file_type:` (which
|
|
89
|
+
those collections lack). See `api/typesense.js:223-249`.
|
|
90
|
+
|
|
91
|
+
## Filter clauses (`filter_by` syntax)
|
|
92
|
+
|
|
93
|
+
All filter clauses are joined with ` && ` (Typesense AND). Each
|
|
94
|
+
clause is wrapped in parentheses by the frontend builders — they
|
|
95
|
+
nest naturally because parens are part of the frontend's clause
|
|
96
|
+
emission, not a wrapper added later. The server-side `/search`
|
|
97
|
+
endpoint strips a *single* outer pair of balanced parens
|
|
98
|
+
(`api/typesense.js:194-212`) before appending the workspace clause.
|
|
99
|
+
|
|
100
|
+
### 1. Tag filter
|
|
101
|
+
|
|
102
|
+
Source: `mixins/search-common-functions.js:194-224`.
|
|
103
|
+
|
|
104
|
+
| Operator | Generated clause |
|
|
105
|
+
| --------------- | ------------------------------------------------------------------ |
|
|
106
|
+
| include-all-of | `tags:[\tag1\] && tags:[\tag2\]` (per-tag clauses joined by `&&`) |
|
|
107
|
+
| include-any-of | `tags:[\tag1\] \|\| tags:[\tag2\]` (joined by `\|\|`) |
|
|
108
|
+
| exclude-all-of | `tags:!=[name1] && tags:!=[name2]` |
|
|
109
|
+
| exclude-any-of | `tags:!=[name1] \|\| tags:!=[name2]` |
|
|
110
|
+
| contains | `tags:*<substring>*` |
|
|
111
|
+
|
|
112
|
+
The MCP contract exposes a simplified `tags: string[]` filter that
|
|
113
|
+
emits the `include-any-of` shape (`tags:=[name1, name2]` per
|
|
114
|
+
spec.md §Filter schema). Advanced operator selection is deferred to
|
|
115
|
+
Phase 2.
|
|
116
|
+
|
|
117
|
+
### 2. File-type filter
|
|
118
|
+
|
|
119
|
+
Source: `mixins/search-common-functions.js:225-239`.
|
|
120
|
+
|
|
121
|
+
| Operator | Clause |
|
|
122
|
+
| -------- | ------------------------------------------------------- |
|
|
123
|
+
| is | `file_type:=image \|\| file_type:=video` (OR-joined) |
|
|
124
|
+
| is not | `file_type:!=image && file_type:!=video` (AND-joined) |
|
|
125
|
+
|
|
126
|
+
MCP contract: `file_type: string[]` → `file_type:=[image,video]`
|
|
127
|
+
(Typesense array shorthand for OR-joined `:=`).
|
|
128
|
+
|
|
129
|
+
### 3. Visibility / permission filter
|
|
130
|
+
|
|
131
|
+
Source: `mixins/search-common-functions.js:85-89`.
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
return ` (visibility${isCondition === isPublic ? ':=' : ':!='}0) `
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Visibility is **numeric**: `0` = public, `1` = private. Per spec
|
|
138
|
+
§Filter schema this was confirmed against Phase 2.5 testing.
|
|
139
|
+
|
|
140
|
+
MCP contract: `visibility: 'public' | 'private' | number` →
|
|
141
|
+
`visibility:=0` / `visibility:=1`.
|
|
142
|
+
|
|
143
|
+
### 4. Date-range filters
|
|
144
|
+
|
|
145
|
+
Source: `mixins/search-common-functions.js:148-193`. All upstream
|
|
146
|
+
date filtering is **unix-second** based.
|
|
147
|
+
|
|
148
|
+
| Field key in request | Typesense field |
|
|
149
|
+
| ------------------------ | --------------- |
|
|
150
|
+
| `date-added` | `created_at` |
|
|
151
|
+
| `last-modified-date` | `modified_at` |
|
|
152
|
+
|
|
153
|
+
Operators emitted:
|
|
154
|
+
|
|
155
|
+
- `after` → `created_at:>=<unix>`
|
|
156
|
+
- `before` → `created_at:<=<unix>`
|
|
157
|
+
- `between` (custom range) →
|
|
158
|
+
`created_at:>=<startUnix> && created_at:<=<endUnix>`
|
|
159
|
+
|
|
160
|
+
Pre-canned slugs: `30-mins-ago`, `1-day-ago`, `3-days-ago`,
|
|
161
|
+
`1-week-ago`, `1-month-ago`, `custom`.
|
|
162
|
+
|
|
163
|
+
MCP contract: `created_after`, `created_before`, `modified_after`,
|
|
164
|
+
`modified_before` — each accepts unix-seconds (number) or ISO-8601
|
|
165
|
+
string (coerced to unix).
|
|
166
|
+
|
|
167
|
+
### 5. Collection-scoped filter (`collage` in frontend)
|
|
168
|
+
|
|
169
|
+
Source: `mixins/search-common-functions.js:240-249`.
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
collection_ids:=[<slug>] && is_collection:=1
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Multiple collections are joined by `||` (is) or `&&` (is-not). Note
|
|
176
|
+
the `is_collection:=1` companion clause — the upstream filters the
|
|
177
|
+
`digital_assets` index for rows that *are* collection-bearing.
|
|
178
|
+
|
|
179
|
+
MCP contract: `collection_ids: (string|number)[]` →
|
|
180
|
+
`collection_ids:=[id1,id2]` (single clause; the `is_collection:=1`
|
|
181
|
+
side-clause is omitted in the MCP surface — we surface raw
|
|
182
|
+
membership).
|
|
183
|
+
|
|
184
|
+
### 6. Category / folder-scoped filter
|
|
185
|
+
|
|
186
|
+
Source: `pages/_workspace_id/dam/folders/_id/index.vue:2920`:
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
const folderFilter = `category_id:=[${folderId}]`
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
MCP contract: `category_id: string|number` → `category_id:=<id>`.
|
|
193
|
+
|
|
194
|
+
### 7. Uploaded-by filter
|
|
195
|
+
|
|
196
|
+
Source: `mixins/search-common-functions.js:318-353`. Emits
|
|
197
|
+
`created_by_id:=<id>` (or `:!=`) per user, joined by `||` for "is"
|
|
198
|
+
and `&&` for "is not", with optional `is_external_upload:=true|false`
|
|
199
|
+
companion clause.
|
|
200
|
+
|
|
201
|
+
Out of scope for the MCP `search_assets` v1 surface — covered by the
|
|
202
|
+
audit/distribution tooling in Phase 2.
|
|
203
|
+
|
|
204
|
+
### 8. Custom-field filter
|
|
205
|
+
|
|
206
|
+
Source: `mixins/search-common-functions.js:255-316`. Emits literal
|
|
207
|
+
clauses like `` custom_fields:=`<field_label>:<value>` `` (note the
|
|
208
|
+
backticks — they are part of the Typesense filter syntax). The MCP
|
|
209
|
+
exposes raw passthrough for now (`custom_fields: string[]`),
|
|
210
|
+
defer-validating the inner shape to the consumer.
|
|
211
|
+
|
|
212
|
+
## Indexed fields (per `digital_assets`)
|
|
213
|
+
|
|
214
|
+
From spec.md §Indexed fields and live frontend usage:
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
id, workspace_id, instances_id, display_file_name, search_name,
|
|
218
|
+
description, file_type, type, thumbnail_file, compress_file,
|
|
219
|
+
video_preview, display_file, file_size, height, width,
|
|
220
|
+
orientation, is_external_upload, visibility, category_id,
|
|
221
|
+
is_collection, collection_ids, created_by, created_by_id,
|
|
222
|
+
created_at, modified_at, tags, custom_fields, breadcrumb
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Surprises worth surfacing
|
|
226
|
+
|
|
227
|
+
1. **`workspace_id` matched against `workspace_unique_id`, not the
|
|
228
|
+
workspace database id.** The frontend resolves
|
|
229
|
+
`workspace_unique_id` via the `/user` endpoint
|
|
230
|
+
(`api/typesense.js:122-132`). For the MCP we treat
|
|
231
|
+
`COLLAGE_WORKSPACE_ID` env as the raw id used in the filter —
|
|
232
|
+
if it turns out Collage's Typesense indexes `workspace_unique_id`
|
|
233
|
+
rather than the workspace db id, we will need to plumb a
|
|
234
|
+
one-time resolution at startup. T1 (Tarang) is the trigger to
|
|
235
|
+
confirm this.
|
|
236
|
+
|
|
237
|
+
2. **`tags:[\tag\]`** uses an *escaped backslash* before the bracket
|
|
238
|
+
when matching exact tag names. Frontend sources show `\\\\` in
|
|
239
|
+
template-literal form which renders to a single backslash in the
|
|
240
|
+
emitted filter. The MCP avoids this escape entirely by using the
|
|
241
|
+
array form `tags:=[name1,name2]` which Typesense interprets
|
|
242
|
+
identically for the include-any-of shape used in the contract.
|
|
243
|
+
|
|
244
|
+
3. **Visibility is numeric** (not the string `"public"`/`"private"`).
|
|
245
|
+
Frontend treats `0` = public, `1` = private. Documented in
|
|
246
|
+
spec.md but worth the second mention because it is easy to get
|
|
247
|
+
wrong.
|
|
248
|
+
|
|
249
|
+
4. **`infix: 'always'`** is enabled by default at the upstream
|
|
250
|
+
middleware. This means a query for "cal" matches "calvin",
|
|
251
|
+
"local", and "optical". Spec callers should set
|
|
252
|
+
`infix: 'off'` if they want strict prefix matching.
|
|
253
|
+
|
|
254
|
+
5. **The frontend sometimes blanks the filter for non-asset
|
|
255
|
+
collections.** When `tags`, `file-type`, `collage`, or
|
|
256
|
+
`uploaded-by` filters are present, the frontend skips the
|
|
257
|
+
`dam_collections` and `digital_assets_categories` searches
|
|
258
|
+
(`mixins/search-common-functions.js:131-141, 396-413`). The
|
|
259
|
+
MCP `search_collections` tool deliberately does NOT carry that
|
|
260
|
+
short-circuit — collection search runs independently of asset
|
|
261
|
+
filters. If a downstream caller needs the frontend's exact
|
|
262
|
+
behaviour, they compose the two tool calls themselves.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Verified Collage API endpoints (historical)
|
|
2
|
+
|
|
3
|
+
> **Superseded 2026-05-04.** This file is the original Phase-2.5 stub
|
|
4
|
+
> that captured the first 5 endpoints we verified against BREZ. It has
|
|
5
|
+
> been superseded by [`api-field-verification.md`](./api-field-verification.md),
|
|
6
|
+
> which now covers ~22 endpoints across asset, tag, folder, collection,
|
|
7
|
+
> share-link, embed, and search surfaces with full Admin-Frontend
|
|
8
|
+
> citations and per-endpoint contract-test references.
|
|
9
|
+
>
|
|
10
|
+
> Kept for git history continuity. Don't update — extend
|
|
11
|
+
> `api-field-verification.md` instead.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Original Phase-1 surface (kept for reference)
|
|
16
|
+
|
|
17
|
+
The endpoints below were the first 5 verified against a live workspace
|
|
18
|
+
(BREZ, `workspace_id=1927483178`). All have since been re-verified by
|
|
19
|
+
contract tests in `tests/contract/`:
|
|
20
|
+
|
|
21
|
+
1. `check-workspace-access` — auth + scoping smoke. Verified by
|
|
22
|
+
`check-workspace-access.contract.test.ts`.
|
|
23
|
+
2. `digital-assets/category/all-category-list` — folder roots.
|
|
24
|
+
Originally 402-blocked; resolved 2026-05-01 (missing `workspace_id`
|
|
25
|
+
query param). Verified by `list-categories.contract.test.ts`. Now
|
|
26
|
+
walked recursively via `listAllCategoriesRecursive()` to recover
|
|
27
|
+
the full tree (the upstream returns roots only by design).
|
|
28
|
+
3. `digital-assets/collection/get-all` — collections list. Verified
|
|
29
|
+
by `list-collections.contract.test.ts`.
|
|
30
|
+
4. `digital-assets/embed-code-list` — embed-code paginator. Verified
|
|
31
|
+
by `list-embed-codes.contract.test.ts`.
|
|
32
|
+
5. `digital-assets/view-detail` — single-asset full metadata. Body
|
|
33
|
+
param is `digital_assets_id` (NOT `asset_id`). Verified by
|
|
34
|
+
`get-asset-details.contract.test.ts`.
|
|
35
|
+
|
|
36
|
+
For the full current state of every endpoint the MCP server uses —
|
|
37
|
+
including share-link, write-side, and search-proxy endpoints — see
|
|
38
|
+
[`api-field-verification.md`](./api-field-verification.md).
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@collage-dam/mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Model Context Protocol (MCP) server for the Collage Digital Asset Management platform. Exposes Collage workspaces — assets, folders, collections, share links, audit prompts — to AI clients (Claude Desktop, Cursor, ChatGPT) through a typed tool surface.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"collage-mcp": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md",
|
|
14
|
+
"CHANGELOG.md",
|
|
15
|
+
"LICENSE",
|
|
16
|
+
".env.example",
|
|
17
|
+
"docs"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"postbuild": "chmod +x dist/index.js",
|
|
22
|
+
"dev": "tsx watch src/index.ts",
|
|
23
|
+
"start": "node dist/index.js",
|
|
24
|
+
"test": "vitest run --exclude 'tests/contract/**' --exclude 'tests/integration/**'",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"test:integration": "INTEGRATION=1 vitest run tests/contract tests/integration",
|
|
27
|
+
"smoke": "tsx scripts/smoke-stdio.ts",
|
|
28
|
+
"prompt": "tsx scripts/dump-prompt.ts",
|
|
29
|
+
"lint": "tsc --noEmit",
|
|
30
|
+
"prepublishOnly": "npm run lint && npm test && npm run build"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"mcp",
|
|
34
|
+
"model-context-protocol",
|
|
35
|
+
"collage",
|
|
36
|
+
"dam",
|
|
37
|
+
"digital-asset-management",
|
|
38
|
+
"claude",
|
|
39
|
+
"ai-tools"
|
|
40
|
+
],
|
|
41
|
+
"author": "Southleft <hello@southleft.com>",
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"homepage": "https://github.com/southleft/collage-mcp#readme",
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/southleft/collage-mcp.git"
|
|
47
|
+
},
|
|
48
|
+
"bugs": {
|
|
49
|
+
"url": "https://github.com/southleft/collage-mcp/issues"
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=20"
|
|
53
|
+
},
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public",
|
|
56
|
+
"registry": "https://registry.npmjs.org/"
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@modelcontextprotocol/sdk": "1.12.1",
|
|
60
|
+
"ioredis": "^5.10.1",
|
|
61
|
+
"pino": "^9.6.0",
|
|
62
|
+
"ulid": "^2.3.0",
|
|
63
|
+
"zod": "^3.24.0"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/ioredis": "^4.28.10",
|
|
67
|
+
"@types/node": "^22.0.0",
|
|
68
|
+
"tsx": "^4.19.0",
|
|
69
|
+
"typescript": "^5.7.0",
|
|
70
|
+
"vitest": "^3.1.0"
|
|
71
|
+
}
|
|
72
|
+
}
|