threenative-asset-mcp 0.4.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.
Files changed (150) hide show
  1. package/README.md +441 -0
  2. package/dist/ambientcg/client.d.ts +61 -0
  3. package/dist/ambientcg/client.d.ts.map +1 -0
  4. package/dist/ambientcg/client.js +234 -0
  5. package/dist/ambientcg/client.js.map +1 -0
  6. package/dist/audio/catalog.d.ts +36 -0
  7. package/dist/audio/catalog.d.ts.map +1 -0
  8. package/dist/audio/catalog.js +169 -0
  9. package/dist/audio/catalog.js.map +1 -0
  10. package/dist/audio/client.d.ts +46 -0
  11. package/dist/audio/client.d.ts.map +1 -0
  12. package/dist/audio/client.js +196 -0
  13. package/dist/audio/client.js.map +1 -0
  14. package/dist/bundle/client.d.ts +89 -0
  15. package/dist/bundle/client.d.ts.map +1 -0
  16. package/dist/bundle/client.js +324 -0
  17. package/dist/bundle/client.js.map +1 -0
  18. package/dist/config.d.ts +20 -0
  19. package/dist/config.d.ts.map +1 -0
  20. package/dist/config.js +130 -0
  21. package/dist/config.js.map +1 -0
  22. package/dist/download/direct-asset-downloader.d.ts +41 -0
  23. package/dist/download/direct-asset-downloader.d.ts.map +1 -0
  24. package/dist/download/direct-asset-downloader.js +232 -0
  25. package/dist/download/direct-asset-downloader.js.map +1 -0
  26. package/dist/fab/api-download.d.ts +30 -0
  27. package/dist/fab/api-download.d.ts.map +1 -0
  28. package/dist/fab/api-download.js +200 -0
  29. package/dist/fab/api-download.js.map +1 -0
  30. package/dist/fab/browser-transport.d.ts +79 -0
  31. package/dist/fab/browser-transport.d.ts.map +1 -0
  32. package/dist/fab/browser-transport.js +492 -0
  33. package/dist/fab/browser-transport.js.map +1 -0
  34. package/dist/fab/cache.d.ts +22 -0
  35. package/dist/fab/cache.d.ts.map +1 -0
  36. package/dist/fab/cache.js +55 -0
  37. package/dist/fab/cache.js.map +1 -0
  38. package/dist/fab/client.d.ts +61 -0
  39. package/dist/fab/client.d.ts.map +1 -0
  40. package/dist/fab/client.js +868 -0
  41. package/dist/fab/client.js.map +1 -0
  42. package/dist/fab/direct-transport.d.ts +68 -0
  43. package/dist/fab/direct-transport.d.ts.map +1 -0
  44. package/dist/fab/direct-transport.js +184 -0
  45. package/dist/fab/direct-transport.js.map +1 -0
  46. package/dist/fab/download-store.d.ts +21 -0
  47. package/dist/fab/download-store.d.ts.map +1 -0
  48. package/dist/fab/download-store.js +93 -0
  49. package/dist/fab/download-store.js.map +1 -0
  50. package/dist/fab/errors.d.ts +20 -0
  51. package/dist/fab/errors.d.ts.map +1 -0
  52. package/dist/fab/errors.js +65 -0
  53. package/dist/fab/errors.js.map +1 -0
  54. package/dist/fab/impersonate-fetch.d.ts +48 -0
  55. package/dist/fab/impersonate-fetch.d.ts.map +1 -0
  56. package/dist/fab/impersonate-fetch.js +228 -0
  57. package/dist/fab/impersonate-fetch.js.map +1 -0
  58. package/dist/fab/normalize.d.ts +3 -0
  59. package/dist/fab/normalize.d.ts.map +1 -0
  60. package/dist/fab/normalize.js +285 -0
  61. package/dist/fab/normalize.js.map +1 -0
  62. package/dist/fab/schemas.d.ts +10 -0
  63. package/dist/fab/schemas.d.ts.map +1 -0
  64. package/dist/fab/schemas.js +105 -0
  65. package/dist/fab/schemas.js.map +1 -0
  66. package/dist/index.d.ts +3 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +58 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/itch/catalog.d.ts +13 -0
  71. package/dist/itch/catalog.d.ts.map +1 -0
  72. package/dist/itch/catalog.js +50 -0
  73. package/dist/itch/catalog.js.map +1 -0
  74. package/dist/itch/client.d.ts +46 -0
  75. package/dist/itch/client.d.ts.map +1 -0
  76. package/dist/itch/client.js +175 -0
  77. package/dist/itch/client.js.map +1 -0
  78. package/dist/polyhaven/client.d.ts +55 -0
  79. package/dist/polyhaven/client.d.ts.map +1 -0
  80. package/dist/polyhaven/client.js +210 -0
  81. package/dist/polyhaven/client.js.map +1 -0
  82. package/dist/server.d.ts +25 -0
  83. package/dist/server.d.ts.map +1 -0
  84. package/dist/server.js +448 -0
  85. package/dist/server.js.map +1 -0
  86. package/dist/sketchfab/client.d.ts +70 -0
  87. package/dist/sketchfab/client.d.ts.map +1 -0
  88. package/dist/sketchfab/client.js +255 -0
  89. package/dist/sketchfab/client.js.map +1 -0
  90. package/dist/smithsonian/client.d.ts +32 -0
  91. package/dist/smithsonian/client.d.ts.map +1 -0
  92. package/dist/smithsonian/client.js +142 -0
  93. package/dist/smithsonian/client.js.map +1 -0
  94. package/dist/tools/ambientcg.d.ts +296 -0
  95. package/dist/tools/ambientcg.d.ts.map +1 -0
  96. package/dist/tools/ambientcg.js +183 -0
  97. package/dist/tools/ambientcg.js.map +1 -0
  98. package/dist/tools/audio.d.ts +211 -0
  99. package/dist/tools/audio.d.ts.map +1 -0
  100. package/dist/tools/audio.js +156 -0
  101. package/dist/tools/audio.js.map +1 -0
  102. package/dist/tools/bundle.d.ts +237 -0
  103. package/dist/tools/bundle.d.ts.map +1 -0
  104. package/dist/tools/bundle.js +206 -0
  105. package/dist/tools/bundle.js.map +1 -0
  106. package/dist/tools/direct-download.d.ts +53 -0
  107. package/dist/tools/direct-download.d.ts.map +1 -0
  108. package/dist/tools/direct-download.js +68 -0
  109. package/dist/tools/direct-download.js.map +1 -0
  110. package/dist/tools/download-free-asset.d.ts +66 -0
  111. package/dist/tools/download-free-asset.d.ts.map +1 -0
  112. package/dist/tools/download-free-asset.js +60 -0
  113. package/dist/tools/download-free-asset.js.map +1 -0
  114. package/dist/tools/get-asset.d.ts +161 -0
  115. package/dist/tools/get-asset.d.ts.map +1 -0
  116. package/dist/tools/get-asset.js +131 -0
  117. package/dist/tools/get-asset.js.map +1 -0
  118. package/dist/tools/itch.d.ts +120 -0
  119. package/dist/tools/itch.d.ts.map +1 -0
  120. package/dist/tools/itch.js +120 -0
  121. package/dist/tools/itch.js.map +1 -0
  122. package/dist/tools/list-filters.d.ts +127 -0
  123. package/dist/tools/list-filters.d.ts.map +1 -0
  124. package/dist/tools/list-filters.js +68 -0
  125. package/dist/tools/list-filters.js.map +1 -0
  126. package/dist/tools/list-limited-time-free.d.ts +57 -0
  127. package/dist/tools/list-limited-time-free.d.ts.map +1 -0
  128. package/dist/tools/list-limited-time-free.js +47 -0
  129. package/dist/tools/list-limited-time-free.js.map +1 -0
  130. package/dist/tools/polyhaven.d.ts +266 -0
  131. package/dist/tools/polyhaven.d.ts.map +1 -0
  132. package/dist/tools/polyhaven.js +233 -0
  133. package/dist/tools/polyhaven.js.map +1 -0
  134. package/dist/tools/search-assets.d.ts +176 -0
  135. package/dist/tools/search-assets.d.ts.map +1 -0
  136. package/dist/tools/search-assets.js +172 -0
  137. package/dist/tools/search-assets.js.map +1 -0
  138. package/dist/tools/sketchfab.d.ts +325 -0
  139. package/dist/tools/sketchfab.d.ts.map +1 -0
  140. package/dist/tools/sketchfab.js +203 -0
  141. package/dist/tools/sketchfab.js.map +1 -0
  142. package/dist/tools/smithsonian.d.ts +189 -0
  143. package/dist/tools/smithsonian.d.ts.map +1 -0
  144. package/dist/tools/smithsonian.js +189 -0
  145. package/dist/tools/smithsonian.js.map +1 -0
  146. package/dist/tools/source-directory.d.ts +226 -0
  147. package/dist/tools/source-directory.d.ts.map +1 -0
  148. package/dist/tools/source-directory.js +583 -0
  149. package/dist/tools/source-directory.js.map +1 -0
  150. package/package.json +69 -0
@@ -0,0 +1,105 @@
1
+ import { z } from "zod";
2
+ export const UpstreamSearchSchema = z
3
+ .object({
4
+ results: z.array(z.unknown()),
5
+ cursors: z
6
+ .object({
7
+ next: z.string().nullable().optional(),
8
+ previous: z.string().nullable().optional(),
9
+ })
10
+ .passthrough()
11
+ .optional(),
12
+ })
13
+ .passthrough();
14
+ export const UpstreamListingSchema = z
15
+ .record(z.string(), z.unknown())
16
+ .superRefine((value, context) => {
17
+ const id = value.uid ?? value.id ?? value.uuid;
18
+ const title = value.title ?? value.name;
19
+ if (typeof id !== "string" || id.length === 0) {
20
+ context.addIssue({
21
+ code: "custom",
22
+ message: "listing identity is missing",
23
+ });
24
+ }
25
+ if (typeof title !== "string" || title.length === 0) {
26
+ context.addIssue({
27
+ code: "custom",
28
+ message: "listing title is missing",
29
+ });
30
+ }
31
+ for (const key of [
32
+ "licenses",
33
+ "offers",
34
+ "assetFormats",
35
+ "asset_formats",
36
+ "formats",
37
+ "media",
38
+ "images",
39
+ "files",
40
+ "tags",
41
+ "categories",
42
+ ]) {
43
+ if (value[key] !== undefined && !Array.isArray(value[key])) {
44
+ context.addIssue({
45
+ code: "custom",
46
+ message: `${key} must be an array when present`,
47
+ path: [key],
48
+ });
49
+ }
50
+ }
51
+ const licenses = value.licenses ?? value.offers;
52
+ if (Array.isArray(licenses)) {
53
+ licenses.forEach((entry, index) => {
54
+ if (typeof entry !== "object" ||
55
+ entry === null ||
56
+ Array.isArray(entry)) {
57
+ context.addIssue({
58
+ code: "custom",
59
+ message: "license entries must be objects",
60
+ path: ["licenses", index],
61
+ });
62
+ return;
63
+ }
64
+ const license = entry;
65
+ for (const priceKey of [
66
+ "price",
67
+ "basePrice",
68
+ "pricing",
69
+ "discountedPrice",
70
+ "effectivePrice",
71
+ "salePrice",
72
+ ]) {
73
+ const rawPrice = license[priceKey];
74
+ if (rawPrice === undefined)
75
+ continue;
76
+ if (typeof rawPrice !== "object" ||
77
+ rawPrice === null ||
78
+ Array.isArray(rawPrice)) {
79
+ context.addIssue({
80
+ code: "custom",
81
+ message: `${priceKey} must be an object`,
82
+ path: ["licenses", index, priceKey],
83
+ });
84
+ continue;
85
+ }
86
+ const price = rawPrice;
87
+ const numeric = [
88
+ price.amount,
89
+ price.price,
90
+ price.value,
91
+ price.effectiveAmount,
92
+ price.discountedAmount,
93
+ ].some((candidate) => typeof candidate === "number" && Number.isFinite(candidate));
94
+ if (!numeric) {
95
+ context.addIssue({
96
+ code: "custom",
97
+ message: `${priceKey} has no numeric price`,
98
+ path: ["licenses", index, priceKey],
99
+ });
100
+ }
101
+ }
102
+ });
103
+ }
104
+ });
105
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/fab/schemas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+ import { serveStdio } from "@modelcontextprotocol/server/stdio";
3
+ import { AmbientCgClient } from "./ambientcg/client.js";
4
+ import { AudioCatalogClient } from "./audio/client.js";
5
+ import { BundleAssetClient } from "./bundle/client.js";
6
+ import { DirectAssetDownloader } from "./download/direct-asset-downloader.js";
7
+ import { FabClient } from "./fab/client.js";
8
+ import { ItchAssetClient } from "./itch/client.js";
9
+ import { PolyHavenClient } from "./polyhaven/client.js";
10
+ import { SketchfabClient } from "./sketchfab/client.js";
11
+ import { createAssetServer } from "./server.js";
12
+ import { SmithsonianClient } from "./smithsonian/client.js";
13
+ const fab = new FabClient();
14
+ const polyhaven = new PolyHavenClient();
15
+ const ambientcg = new AmbientCgClient();
16
+ const smithsonian = new SmithsonianClient();
17
+ const sketchfab = new SketchfabClient();
18
+ const audio = new AudioCatalogClient();
19
+ const directDownloader = new DirectAssetDownloader();
20
+ const itch = new ItchAssetClient({ downloader: directDownloader });
21
+ const bundle = new BundleAssetClient({ itch });
22
+ void fab.prepareBrowser();
23
+ const handle = serveStdio(() => createAssetServer({
24
+ fab,
25
+ polyhaven,
26
+ ambientcg,
27
+ smithsonian,
28
+ sketchfab,
29
+ audio,
30
+ directDownloader,
31
+ itch,
32
+ bundle,
33
+ }), {
34
+ onerror(error) {
35
+ process.stderr.write(`${JSON.stringify({
36
+ level: "error",
37
+ message: "MCP transport error",
38
+ error: error.name,
39
+ })}\n`);
40
+ },
41
+ });
42
+ let closing = false;
43
+ async function shutdown() {
44
+ if (closing)
45
+ return;
46
+ closing = true;
47
+ await Promise.allSettled([fab.close(), handle.close()]);
48
+ }
49
+ process.once("SIGINT", () => {
50
+ void shutdown().finally(() => process.exit(0));
51
+ });
52
+ process.once("SIGTERM", () => {
53
+ void shutdown().finally(() => process.exit(0));
54
+ });
55
+ process.once("beforeExit", () => {
56
+ void shutdown();
57
+ });
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC;AAC5B,MAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;AACxC,MAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;AACxC,MAAM,WAAW,GAAG,IAAI,iBAAiB,EAAE,CAAC;AAC5C,MAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;AACxC,MAAM,KAAK,GAAG,IAAI,kBAAkB,EAAE,CAAC;AACvC,MAAM,gBAAgB,GAAG,IAAI,qBAAqB,EAAE,CAAC;AACrD,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC,CAAC;AACnE,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,KAAK,GAAG,CAAC,cAAc,EAAE,CAAC;AAC1B,MAAM,MAAM,GAAG,UAAU,CACvB,GAAG,EAAE,CACH,iBAAiB,CAAC;IAChB,GAAG;IACH,SAAS;IACT,SAAS;IACT,WAAW;IACX,SAAS;IACT,KAAK;IACL,gBAAgB;IAChB,IAAI;IACJ,MAAM;CACP,CAAC,EACJ;IACA,OAAO,CAAC,KAAK;QACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,CAAC,SAAS,CAAC;YAChB,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,qBAAqB;YAC9B,KAAK,EAAE,KAAK,CAAC,IAAI;SAClB,CAAC,IAAI,CACP,CAAC;IACJ,CAAC;CACA,CACF,CAAC;AAEF,IAAI,OAAO,GAAG,KAAK,CAAC;AACpB,KAAK,UAAU,QAAQ;IACrB,IAAI,OAAO;QAAE,OAAO;IACpB,OAAO,GAAG,IAAI,CAAC;IACf,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;IAC1B,KAAK,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;IAC3B,KAAK,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE;IAC9B,KAAK,QAAQ,EAAE,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ export type ItchPackId = "tallbeard-music-loop-bundle" | "quaternius-universal-animation-library-1" | "quaternius-universal-animation-library-2" | "brackeys-vfx-bundle" | "kaykit-platformer";
2
+ export interface ItchPack {
3
+ id: ItchPackId;
4
+ name: string;
5
+ sourceId: string;
6
+ pageUrl: string;
7
+ kind: "music" | "animation" | "vfx" | "3d-model";
8
+ license: "CC0";
9
+ attributionRequired: false;
10
+ caution?: string;
11
+ }
12
+ export declare const ITCH_PACKS: readonly ItchPack[];
13
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/itch/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,6BAA6B,GAC7B,0CAA0C,GAC1C,0CAA0C,GAC1C,qBAAqB,GACrB,mBAAmB,CAAC;AAExB,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,UAAU,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,KAAK,GAAG,UAAU,CAAC;IACjD,OAAO,EAAE,KAAK,CAAC;IACf,mBAAmB,EAAE,KAAK,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,UAAU,EAAE,SAAS,QAAQ,EAgDhC,CAAC"}
@@ -0,0 +1,50 @@
1
+ export const ITCH_PACKS = [
2
+ {
3
+ id: "tallbeard-music-loop-bundle",
4
+ name: "Tallbeard Music Loop Bundle",
5
+ sourceId: "tallbeard",
6
+ pageUrl: "https://tallbeard.itch.io/music-loop-bundle",
7
+ kind: "music",
8
+ license: "CC0",
9
+ attributionRequired: false,
10
+ caution: "Credit to Abstraction is optional but appreciated by the creator.",
11
+ },
12
+ {
13
+ id: "quaternius-universal-animation-library-1",
14
+ name: "Quaternius Universal Animation Library 1",
15
+ sourceId: "quaternius",
16
+ pageUrl: "https://quaternius.itch.io/universal-animation-library",
17
+ kind: "animation",
18
+ license: "CC0",
19
+ attributionRequired: false,
20
+ },
21
+ {
22
+ id: "quaternius-universal-animation-library-2",
23
+ name: "Quaternius Universal Animation Library 2",
24
+ sourceId: "quaternius",
25
+ pageUrl: "https://quaternius.itch.io/universal-animation-library-2",
26
+ kind: "animation",
27
+ license: "CC0",
28
+ attributionRequired: false,
29
+ },
30
+ {
31
+ id: "brackeys-vfx-bundle",
32
+ name: "Brackeys VFX Bundle",
33
+ sourceId: "brackeys-vfx",
34
+ pageUrl: "https://brackeysgames.itch.io/brackeys-vfx-bundle",
35
+ kind: "vfx",
36
+ license: "CC0",
37
+ attributionRequired: false,
38
+ },
39
+ {
40
+ id: "kaykit-platformer",
41
+ name: "KayKit Platformer Pack",
42
+ sourceId: "kaykit",
43
+ pageUrl: "https://kaylousberg.itch.io/kaykit-platformer",
44
+ kind: "3d-model",
45
+ license: "CC0",
46
+ attributionRequired: false,
47
+ caution: "Do not resell the unmodified pack or claim it as your own.",
48
+ },
49
+ ];
50
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/itch/catalog.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,UAAU,GAAwB;IAC7C;QACE,EAAE,EAAE,6BAA6B;QACjC,IAAI,EAAE,6BAA6B;QACnC,QAAQ,EAAE,WAAW;QACrB,OAAO,EAAE,6CAA6C;QACtD,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,KAAK;QACd,mBAAmB,EAAE,KAAK;QAC1B,OAAO,EAAE,mEAAmE;KAC7E;IACD;QACE,EAAE,EAAE,0CAA0C;QAC9C,IAAI,EAAE,0CAA0C;QAChD,QAAQ,EAAE,YAAY;QACtB,OAAO,EAAE,wDAAwD;QACjE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,KAAK;QACd,mBAAmB,EAAE,KAAK;KAC3B;IACD;QACE,EAAE,EAAE,0CAA0C;QAC9C,IAAI,EAAE,0CAA0C;QAChD,QAAQ,EAAE,YAAY;QACtB,OAAO,EAAE,0DAA0D;QACnE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,KAAK;QACd,mBAAmB,EAAE,KAAK;KAC3B;IACD;QACE,EAAE,EAAE,qBAAqB;QACzB,IAAI,EAAE,qBAAqB;QAC3B,QAAQ,EAAE,cAAc;QACxB,OAAO,EAAE,mDAAmD;QAC5D,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,KAAK;QACd,mBAAmB,EAAE,KAAK;KAC3B;IACD;QACE,EAAE,EAAE,mBAAmB;QACvB,IAAI,EAAE,wBAAwB;QAC9B,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,+CAA+C;QACxD,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,KAAK;QACd,mBAAmB,EAAE,KAAK;QAC1B,OAAO,EAAE,4DAA4D;KACtE;CACO,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { DirectAssetDownloader } from "../download/direct-asset-downloader.js";
2
+ import { type ItchPack, type ItchPackId } from "./catalog.js";
3
+ export interface ItchDownloadEntry {
4
+ uploadId: string;
5
+ name: string;
6
+ sizeLabel?: string;
7
+ suggestedFileName: string;
8
+ }
9
+ export interface ItchPackDownloads {
10
+ pack: ItchPack;
11
+ downloads: ItchDownloadEntry[];
12
+ }
13
+ export interface ResolvedItchUpload {
14
+ pack: ItchPack;
15
+ upload: ItchDownloadEntry;
16
+ signedFileUrl: string;
17
+ }
18
+ export declare class ItchAssetError extends Error {
19
+ readonly code: "ITCH_PACK_NOT_FOUND" | "ITCH_UPLOAD_NOT_FOUND" | "ITCH_UPSTREAM_DENIED" | "ITCH_UPSTREAM_CHANGED" | "ITCH_UNSAFE_URL";
20
+ readonly retryable: boolean;
21
+ constructor(code: "ITCH_PACK_NOT_FOUND" | "ITCH_UPLOAD_NOT_FOUND" | "ITCH_UPSTREAM_DENIED" | "ITCH_UPSTREAM_CHANGED" | "ITCH_UNSAFE_URL", message: string, retryable?: boolean);
22
+ }
23
+ export interface ItchAssetClientOptions {
24
+ fetch?: typeof globalThis.fetch;
25
+ downloader?: DirectAssetDownloader;
26
+ timeoutMs?: number;
27
+ }
28
+ export declare class ItchAssetClient {
29
+ private readonly fetch;
30
+ private readonly downloader;
31
+ private readonly timeoutMs;
32
+ constructor(options?: ItchAssetClientOptions);
33
+ getPack(packId: ItchPackId): ItchPack;
34
+ listDownloads(packId: ItchPackId): Promise<ItchPackDownloads>;
35
+ download(packId: ItchPackId, uploadId: string): Promise<{
36
+ pack: ItchPack;
37
+ upload: ItchDownloadEntry;
38
+ result: import("../download/direct-asset-downloader.js").DirectAssetDownloadResult;
39
+ }>;
40
+ resolveUpload(packId: ItchPackId, uploadId: string): Promise<ResolvedItchUpload>;
41
+ private resolveDownloadPage;
42
+ private requestJson;
43
+ private validateSignedPageUrl;
44
+ private validateSignedFileUrl;
45
+ }
46
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/itch/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAC/E,OAAO,EAAc,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,iBAAiB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,iBAAiB,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,cAAe,SAAQ,KAAK;aAErB,IAAI,EAChB,qBAAqB,GACrB,uBAAuB,GACvB,sBAAsB,GACtB,uBAAuB,GACvB,iBAAiB;aAEL,SAAS;IAR3B,YACkB,IAAI,EAChB,qBAAqB,GACrB,uBAAuB,GACvB,sBAAsB,GACtB,uBAAuB,GACvB,iBAAiB,EACrB,OAAO,EAAE,MAAM,EACC,SAAS,UAAQ,EAIlC;CACF;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6CD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwB;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,YAAY,OAAO,GAAE,sBAA2B,EAI/C;IAED,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,CASpC;IAEK,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAGlE;IAEK,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM;;;;OAalD;IAEK,aAAa,CACjB,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,kBAAkB,CAAC,CAwB7B;YAEa,mBAAmB;YAuCnB,WAAW;IAiCzB,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,qBAAqB;CAwB9B"}
@@ -0,0 +1,175 @@
1
+ import { DirectAssetDownloader } from "../download/direct-asset-downloader.js";
2
+ import { ITCH_PACKS } from "./catalog.js";
3
+ export class ItchAssetError extends Error {
4
+ code;
5
+ retryable;
6
+ constructor(code, message, retryable = false) {
7
+ super(message);
8
+ this.code = code;
9
+ this.retryable = retryable;
10
+ this.name = "ItchAssetError";
11
+ }
12
+ }
13
+ function decodeHtml(value) {
14
+ return value
15
+ .replace(/&amp;/g, "&")
16
+ .replace(/&quot;/g, '"')
17
+ .replace(/&#39;|&#x27;/g, "'")
18
+ .replace(/&lt;/g, "<")
19
+ .replace(/&gt;/g, ">");
20
+ }
21
+ function safeSuggestedFileName(name) {
22
+ const cleaned = name.replace(/[\\/:*?"<>|]/g, "_").trim().slice(0, 200);
23
+ return /\.[A-Za-z0-9]{2,5}$/.test(cleaned) ? cleaned : `${cleaned}.zip`;
24
+ }
25
+ function parseDownloads(html) {
26
+ const entries = [];
27
+ const uploadPattern = /data-upload_id="(\d+)"/g;
28
+ for (const match of html.matchAll(uploadPattern)) {
29
+ const uploadId = match[1];
30
+ if (!uploadId || match.index === undefined)
31
+ continue;
32
+ const window = html.slice(match.index, match.index + 2_000);
33
+ const nameMatch = window.match(/<strong[^>]*title="([^"]+)"[^>]*>/i);
34
+ if (!nameMatch?.[1])
35
+ continue;
36
+ const sizeMatch = window.match(/class="file_size"[^>]*>\s*<span[^>]*>([^<]+)<\/span>/i);
37
+ const name = decodeHtml(nameMatch[1]).trim();
38
+ entries.push({
39
+ uploadId,
40
+ name,
41
+ ...(sizeMatch?.[1] ? { sizeLabel: decodeHtml(sizeMatch[1]).trim() } : {}),
42
+ suggestedFileName: safeSuggestedFileName(name),
43
+ });
44
+ }
45
+ return entries;
46
+ }
47
+ function object(value) {
48
+ return typeof value === "object" && value !== null && !Array.isArray(value)
49
+ ? value
50
+ : undefined;
51
+ }
52
+ export class ItchAssetClient {
53
+ fetch;
54
+ downloader;
55
+ timeoutMs;
56
+ constructor(options = {}) {
57
+ this.fetch = options.fetch ?? globalThis.fetch;
58
+ this.downloader = options.downloader ?? new DirectAssetDownloader();
59
+ this.timeoutMs = options.timeoutMs ?? 30_000;
60
+ }
61
+ getPack(packId) {
62
+ const pack = ITCH_PACKS.find((candidate) => candidate.id === packId);
63
+ if (!pack) {
64
+ throw new ItchAssetError("ITCH_PACK_NOT_FOUND", "The requested itch.io pack is not in the curated catalog.");
65
+ }
66
+ return pack;
67
+ }
68
+ async listDownloads(packId) {
69
+ const { pack, downloads } = await this.resolveDownloadPage(packId);
70
+ return { pack, downloads };
71
+ }
72
+ async download(packId, uploadId) {
73
+ const { pack, upload: selected, signedFileUrl } = await this.resolveUpload(packId, uploadId);
74
+ const result = await this.downloader.download({
75
+ provider: "itch",
76
+ url: signedFileUrl,
77
+ fileName: selected.suggestedFileName,
78
+ identity: `${pack.id}:${selected.uploadId}`,
79
+ reportedSourceUrl: pack.pageUrl,
80
+ });
81
+ return { pack, upload: selected, result };
82
+ }
83
+ async resolveUpload(packId, uploadId) {
84
+ const { pack, downloads, signedPageUrl } = await this.resolveDownloadPage(packId);
85
+ const selected = downloads.find((entry) => entry.uploadId === uploadId);
86
+ if (!selected) {
87
+ throw new ItchAssetError("ITCH_UPLOAD_NOT_FOUND", "The requested upload ID is not present on the freshly resolved itch.io download page.");
88
+ }
89
+ const fileResponse = await this.requestJson(`${pack.pageUrl}/file/${encodeURIComponent(uploadId)}?source=game_download`, signedPageUrl);
90
+ const signedFileUrl = fileResponse.url;
91
+ if (typeof signedFileUrl !== "string") {
92
+ throw new ItchAssetError("ITCH_UPSTREAM_CHANGED", "itch.io did not return a signed file URL.");
93
+ }
94
+ this.validateSignedFileUrl(signedFileUrl);
95
+ return { pack, upload: selected, signedFileUrl };
96
+ }
97
+ async resolveDownloadPage(packId) {
98
+ const pack = this.getPack(packId);
99
+ const response = await this.requestJson(`${pack.pageUrl}/download_url`);
100
+ const signedPageUrl = response.url;
101
+ if (typeof signedPageUrl !== "string") {
102
+ throw new ItchAssetError("ITCH_UPSTREAM_CHANGED", "itch.io did not return a signed download page URL.");
103
+ }
104
+ this.validateSignedPageUrl(pack, signedPageUrl);
105
+ const page = await this.fetch(signedPageUrl, {
106
+ redirect: "error",
107
+ signal: AbortSignal.timeout(this.timeoutMs),
108
+ headers: { "user-agent": "threenative-asset-mcp/0.4.0" },
109
+ });
110
+ if (!page.ok) {
111
+ throw new ItchAssetError("ITCH_UPSTREAM_DENIED", `itch.io returned HTTP ${page.status} for the signed download page.`, page.status === 429 || page.status >= 500);
112
+ }
113
+ const html = await page.text();
114
+ const downloads = parseDownloads(html);
115
+ if (downloads.length === 0) {
116
+ throw new ItchAssetError("ITCH_UPSTREAM_CHANGED", "itch.io returned a download page without recognizable uploads.");
117
+ }
118
+ return { pack, downloads, signedPageUrl };
119
+ }
120
+ async requestJson(url, referer) {
121
+ const response = await this.fetch(url, {
122
+ method: "POST",
123
+ redirect: "error",
124
+ signal: AbortSignal.timeout(this.timeoutMs),
125
+ headers: {
126
+ accept: "application/json",
127
+ "user-agent": "threenative-asset-mcp/0.4.0",
128
+ ...(referer ? { referer } : {}),
129
+ },
130
+ });
131
+ if (!response.ok) {
132
+ throw new ItchAssetError("ITCH_UPSTREAM_DENIED", `itch.io returned HTTP ${response.status}.`, response.status === 429 || response.status >= 500);
133
+ }
134
+ try {
135
+ const parsed = object(await response.json());
136
+ if (!parsed)
137
+ throw new Error("not an object");
138
+ return parsed;
139
+ }
140
+ catch {
141
+ throw new ItchAssetError("ITCH_UPSTREAM_CHANGED", "itch.io returned invalid JSON.");
142
+ }
143
+ }
144
+ validateSignedPageUrl(pack, value) {
145
+ let signed;
146
+ const page = new URL(pack.pageUrl);
147
+ try {
148
+ signed = new URL(value);
149
+ }
150
+ catch {
151
+ throw new ItchAssetError("ITCH_UNSAFE_URL", "itch.io returned an invalid URL.");
152
+ }
153
+ if (signed.protocol !== "https:" ||
154
+ signed.origin !== page.origin ||
155
+ !signed.pathname.startsWith(`${page.pathname}/download/`)) {
156
+ throw new ItchAssetError("ITCH_UNSAFE_URL", "itch.io returned a signed page URL outside the curated pack origin.");
157
+ }
158
+ }
159
+ validateSignedFileUrl(value) {
160
+ let signed;
161
+ try {
162
+ signed = new URL(value);
163
+ }
164
+ catch {
165
+ throw new ItchAssetError("ITCH_UNSAFE_URL", "itch.io returned an invalid file URL.");
166
+ }
167
+ if (signed.protocol !== "https:" ||
168
+ !/^itchio-mirror\.[0-9a-f]+\.r2\.cloudflarestorage\.com$/i.test(signed.hostname) ||
169
+ !/^\/upload2\/game\/\d+\/\d+$/.test(signed.pathname) ||
170
+ !signed.searchParams.has("X-Amz-Signature")) {
171
+ throw new ItchAssetError("ITCH_UNSAFE_URL", "itch.io returned a signed file URL outside its official mirror contract.");
172
+ }
173
+ }
174
+ }
175
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/itch/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ export type PolyHavenAssetType = "hdris" | "textures" | "models";
2
+ export interface PolyHavenAsset {
3
+ id: string;
4
+ name: string;
5
+ description?: string;
6
+ type: PolyHavenAssetType;
7
+ category?: string;
8
+ categoryId?: string;
9
+ tags: string[];
10
+ authors: Record<string, string>;
11
+ attributes: Record<string, unknown>;
12
+ thumbnailUrl?: string;
13
+ maxResolution?: number[];
14
+ dimensions?: number[];
15
+ polycount?: number;
16
+ downloadCount?: number;
17
+ publishedAt?: string;
18
+ filesHash?: string;
19
+ donated?: boolean;
20
+ lods?: boolean;
21
+ }
22
+ export interface PolyHavenFile {
23
+ path: string;
24
+ url: string;
25
+ sizeBytes: number;
26
+ md5: string;
27
+ dependencyOf?: string;
28
+ relativePath?: string;
29
+ }
30
+ export declare class PolyHavenClientError extends Error {
31
+ readonly code: "POLYHAVEN_INVALID_INPUT" | "POLYHAVEN_NOT_FOUND" | "POLYHAVEN_RATE_LIMITED" | "POLYHAVEN_UPSTREAM_UNAVAILABLE" | "POLYHAVEN_UPSTREAM_CHANGED";
32
+ readonly retryable: boolean;
33
+ constructor(code: "POLYHAVEN_INVALID_INPUT" | "POLYHAVEN_NOT_FOUND" | "POLYHAVEN_RATE_LIMITED" | "POLYHAVEN_UPSTREAM_UNAVAILABLE" | "POLYHAVEN_UPSTREAM_CHANGED", message: string, retryable?: boolean);
34
+ }
35
+ type FetchLike = typeof fetch;
36
+ export declare class PolyHavenClient {
37
+ private readonly fetchImpl;
38
+ private readonly cache;
39
+ private readonly timeoutMs;
40
+ private readonly userAgent;
41
+ constructor(fetchImpl?: FetchLike, options?: {
42
+ timeoutMs?: number;
43
+ userAgent?: string;
44
+ });
45
+ private request;
46
+ listAssets(type: PolyHavenAssetType | "all"): Promise<PolyHavenAsset[]>;
47
+ getAsset(id: string): Promise<PolyHavenAsset>;
48
+ listFiles(id: string): Promise<PolyHavenFile[]>;
49
+ listCategories(type: PolyHavenAssetType): Promise<Array<{
50
+ name: string;
51
+ assetCount: number;
52
+ }>>;
53
+ }
54
+ export {};
55
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/polyhaven/client.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAE3C,QAAQ,CAAC,IAAI,EACT,yBAAyB,GACzB,qBAAqB,GACrB,wBAAwB,GACxB,gCAAgC,GAChC,4BAA4B;IAEhC,QAAQ,CAAC,SAAS;IARpB,YACW,IAAI,EACT,yBAAyB,GACzB,qBAAqB,GACrB,wBAAwB,GACxB,gCAAgC,GAChC,4BAA4B,EAChC,OAAO,EAAE,MAAM,EACN,SAAS,UAAQ,EAI3B;CACF;AAED,KAAK,SAAS,GAAG,OAAO,KAAK,CAAC;AA+J9B,qBAAa,eAAe;IAMxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,YACmB,SAAS,GAAE,SAAiB,EAC7C,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,EAKzD;YAEa,OAAO;IAqDf,UAAU,CAAC,IAAI,EAAE,kBAAkB,GAAG,KAAK,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAY5E;IAEK,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAKlD;IAEK,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAIpD;IAEK,cAAc,CAClB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAiBtD;CACF"}