@tinify-ai/mcp-server 1.3.0 → 1.4.1

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 (44) hide show
  1. package/README.md +37 -8
  2. package/dist/api/auth.d.ts +1 -1
  3. package/dist/api/auth.d.ts.map +1 -1
  4. package/dist/api/auth.js +2 -9
  5. package/dist/api/auth.js.map +1 -1
  6. package/dist/api/client.d.ts +6 -0
  7. package/dist/api/client.d.ts.map +1 -1
  8. package/dist/api/client.js +15 -0
  9. package/dist/api/client.js.map +1 -1
  10. package/dist/api/process.d.ts +3 -2
  11. package/dist/api/process.d.ts.map +1 -1
  12. package/dist/api/process.js.map +1 -1
  13. package/dist/auth/anonymous.d.ts +10 -0
  14. package/dist/auth/anonymous.d.ts.map +1 -0
  15. package/dist/auth/anonymous.js +37 -0
  16. package/dist/auth/anonymous.js.map +1 -0
  17. package/dist/auth/context.d.ts +13 -0
  18. package/dist/auth/context.d.ts.map +1 -0
  19. package/dist/auth/context.js +10 -0
  20. package/dist/auth/context.js.map +1 -0
  21. package/dist/auth/jwt.d.ts +7 -0
  22. package/dist/auth/jwt.d.ts.map +1 -0
  23. package/dist/auth/jwt.js +35 -0
  24. package/dist/auth/jwt.js.map +1 -0
  25. package/dist/auth/resolver.d.ts +11 -0
  26. package/dist/auth/resolver.d.ts.map +1 -0
  27. package/dist/auth/resolver.js +35 -0
  28. package/dist/auth/resolver.js.map +1 -0
  29. package/dist/index.js +195 -178
  30. package/dist/index.js.map +1 -1
  31. package/dist/tools/login.js +1 -1
  32. package/dist/tools/login.js.map +1 -1
  33. package/dist/tools/optimize.d.ts +9 -2
  34. package/dist/tools/optimize.d.ts.map +1 -1
  35. package/dist/tools/optimize.js +35 -8
  36. package/dist/tools/optimize.js.map +1 -1
  37. package/dist/tools/status.d.ts.map +1 -1
  38. package/dist/tools/status.js +3 -6
  39. package/dist/tools/status.js.map +1 -1
  40. package/dist/transport/http.d.ts +8 -0
  41. package/dist/transport/http.d.ts.map +1 -0
  42. package/dist/transport/http.js +151 -0
  43. package/dist/transport/http.js.map +1 -0
  44. package/package.json +11 -5
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
5
  [![MCP](https://img.shields.io/badge/MCP-Compatible-brightgreen.svg)](https://modelcontextprotocol.io)
6
6
 
7
- MCP server for [tinify.ai](https://tinify.ai) image optimization. AI-powered upscaling, resizing/cropping, compression, and SEO tag generation — all in one tool.
7
+ MCP server for [tinify.ai](https://tinify.ai) image optimization. AI-powered upscaling, resizing/cropping, compression, and SEO filename & alt text generation — all in one tool.
8
8
 
9
9
  ## Quick Start
10
10
 
@@ -140,12 +140,15 @@ Optimizes an image with smart lossy compression (typically 60-80% size reduction
140
140
  |-----------|------|----------|---------|-------------|
141
141
  | `input` | string | Yes | — | Absolute local file path or remote URL |
142
142
  | `output_path` | string | No | auto | File path or directory (ending in `/`). If omitted: saves next to original with SEO slug or `.tinified` suffix |
143
- | `output_format` | string | No | original | `jpeg`, `png`, `webp`, or `original` |
143
+ | `output_format` | string | No | original | `jpg`, `png`, `webp`, `avif`, `gif`, or `original` |
144
144
  | `output_width_px` | int | No | — | Target width in pixels |
145
145
  | `output_height_px` | int | No | — | Target height in pixels |
146
- | `output_upscale_factor` | float | No | — | AI upscale factor (e.g. 2.0, 4.0) |
146
+ | `output_upscale_factor` | int | No | — | AI upscale factor: `2` (2×) or `4` (4×) |
147
147
  | `output_resize_behavior` | string | No | pad | `pad` (white padding) or `crop` (smart crop). Only used when both width and height are set |
148
148
  | `output_seo_tag_gen` | bool | No | true | Generate SEO metadata and rename file to SEO slug. Costs 1 extra credit |
149
+ | `output_file_size_limit` | int | No | — | Target maximum output file size in bytes. Server attempts to meet this via additional compression. Not guaranteed |
150
+ | `gif_frame_limit` | int | No | 100 | Max frames to process for animated GIFs (1–100). Reduces credit cost by sampling fewer frames |
151
+ | `confirm_gif_cost` | bool | No | — | Set to `true` to proceed after reviewing the animated GIF cost warning. Required for animated GIFs |
149
152
 
150
153
  ### Resize Behavior
151
154
 
@@ -244,19 +247,45 @@ Alt text: Modern office workspace with laptop and coffee cup on wooden desk
244
247
  | WebP | Yes | Yes | |
245
248
  | AVIF | Yes | Yes | |
246
249
  | GIF | Yes | Yes | Animated GIFs preserved when output is GIF |
250
+ | SVG | Yes | Yes | SVG→SVG optimized via SVGO; raster↔SVG conversion supported |
251
+ | ICO | Yes | Yes | Smart rebuild: generates 16, 24, 32, 48, 256px favicon set |
247
252
  | HEIC/HEIF | Yes* | No | Auto-converted to JPG at upload |
248
253
  | TIFF | Yes* | No | Auto-converted to JPG at upload |
249
254
  | BMP | Yes* | No | Auto-converted to JPG at upload |
250
255
 
251
- Tinify supports high-quality conversion between any input and output format combination. Converting an animated GIF to a non-GIF format (JPG, PNG, WebP, AVIF) preserves only the first frame.
256
+ tinify.ai supports high-quality conversion between any input and output format combination.
257
+ Converting an animated GIF to a non-GIF format (JPG, PNG, WebP, AVIF) preserves only the first frame.
258
+ Converting an animated GIF to a GIF format supports upscaling/resizing while preserving the animation and quality. You may also reduce animated GIF file size by decreasing the number of output frames.
252
259
 
253
- Max file size: 50 MB.
260
+ Max upload file size: 50 MB.
261
+
262
+ ### SVG & ICO Examples
263
+
264
+ ```
265
+ # Optimize an SVG file (keeps as vector)
266
+ Optimize logo.svg and keep it as SVG
267
+
268
+ # Convert SVG to raster
269
+ Convert icon.svg to a 512x512 PNG
270
+
271
+ # Trace raster to vector SVG
272
+ Convert my logo.png to a vector SVG
273
+
274
+ # Generate favicon set from any image
275
+ Convert logo.png to an ICO favicon
276
+
277
+ # Generate single-size ICO
278
+ Convert logo.png to a 32x32 ICO
279
+
280
+ # Extract largest icon from ICO
281
+ Convert favicon.ico to PNG
282
+ ```
254
283
 
255
284
  ## How It Works
256
285
 
257
286
  ```
258
287
  Local file or URL
259
- → Upload to Tinify API
288
+ → Upload to Tinify.ai API
260
289
  → Smart compression (lossy, typically 60-80% reduction)
261
290
  → AI SEO tag generation (alt text, keywords, filename)
262
291
  → Optional: resize, upscale, format conversion
@@ -264,7 +293,7 @@ Local file or URL
264
293
  → Save with SEO filename slug (or .tinified suffix if SEO disabled)
265
294
  ```
266
295
 
267
- All processing happens server-side via the [Tinify API](https://tinify.ai). The MCP server is a thin client that orchestrates the pipeline.
296
+ All processing happens server-side via the [Tinify.ai API](https://api.tinify.ai). The MCP server is a thin client that orchestrates the pipeline.
268
297
 
269
298
  ## Credits
270
299
 
@@ -319,7 +348,7 @@ Opens [tinify.ai/pricing](https://tinify.ai/pricing) in your browser.
319
348
  Paste this into your `CLAUDE.md` or system prompt to help agents use the tool effectively:
320
349
 
321
350
  ```
322
- ## Tinify MCP
351
+ ## Tinify.ai MCP
323
352
 
324
353
  Tools: optimize_image, login, logout, status, upgrade
325
354
 
@@ -25,5 +25,5 @@ export interface AccountStatus {
25
25
  export declare function requestDeviceCode(baseUrl: string): Promise<DeviceCodeResponse>;
26
26
  export declare function pollForToken(baseUrl: string, deviceCode: string): Promise<TokenPollResponse>;
27
27
  export declare function revokeToken(baseUrl: string, mcpToken: string): Promise<void>;
28
- export declare function getAccountStatus(baseUrl: string, mcpToken: string | null, sessionToken: string | null): Promise<AccountStatus>;
28
+ export declare function getAccountStatus(baseUrl: string, authHeaders: Record<string, string>): Promise<AccountStatus>;
29
29
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/api/auth.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAOpF;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAOlG;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASlF;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,YAAY,EAAE,MAAM,GAAG,IAAI,GAC1B,OAAO,CAAC,aAAa,CAAC,CAaxB"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/api/auth.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAOpF;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAOlG;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASlF;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,OAAO,CAAC,aAAa,CAAC,CAOxB"}
package/dist/api/auth.js CHANGED
@@ -25,15 +25,8 @@ export async function revokeToken(baseUrl, mcpToken) {
25
25
  throw new ApiError(body.detail || "Token revocation failed", response.status);
26
26
  }
27
27
  }
28
- export async function getAccountStatus(baseUrl, mcpToken, sessionToken) {
29
- const headers = {};
30
- if (mcpToken) {
31
- headers.Authorization = `Bearer ${mcpToken}`;
32
- }
33
- else if (sessionToken) {
34
- headers["X-Session-Token"] = sessionToken;
35
- }
36
- const response = await fetch(`${baseUrl}/mcp/auth/status`, { headers });
28
+ export async function getAccountStatus(baseUrl, authHeaders) {
29
+ const response = await fetch(`${baseUrl}/mcp/auth/status`, { headers: authHeaders });
37
30
  if (!response.ok) {
38
31
  const body = await response.json().catch(() => ({}));
39
32
  throw new ApiError(body.detail || "Status check failed", response.status);
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/api/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA6BvC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAe;IACrD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,uBAAuB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,8BAA8B,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrF,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAe,EAAE,UAAkB;IACpE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,+BAA+B,UAAU,EAAE,CAAC,CAAC;IACpF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe,EAAE,QAAgB;IACjE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,kBAAkB,EAAE;QACzD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,QAAQ,EAAE,EAAE;KACjD,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChF,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAe,EACf,QAAuB,EACvB,YAA2B;IAE3B,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,aAAa,GAAG,UAAU,QAAQ,EAAE,CAAC;IAC/C,CAAC;SAAM,IAAI,YAAY,EAAE,CAAC;QACxB,OAAO,CAAC,iBAAiB,CAAC,GAAG,YAAY,CAAC;IAC5C,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,kBAAkB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACxE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/api/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA6BvC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAe;IACrD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,uBAAuB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,8BAA8B,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrF,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAe,EAAE,UAAkB;IACpE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,+BAA+B,UAAU,EAAE,CAAC,CAAC;IACpF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe,EAAE,QAAgB;IACjE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,kBAAkB,EAAE;QACzD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,QAAQ,EAAE,EAAE;KACjD,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChF,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAe,EACf,WAAmC;IAEnC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,kBAAkB,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;IACrF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC"}
@@ -8,4 +8,10 @@ export declare class ApiError extends Error {
8
8
  readonly detail?: string | undefined;
9
9
  constructor(message: string, status: number, detail?: string | undefined);
10
10
  }
11
+ /**
12
+ * Returns auth headers for an API call.
13
+ * In HTTP mode (request context present): uses per-request auth from context.
14
+ * In stdio mode (no context): reads from ~/.tinify/session.json via SessionManager.
15
+ */
16
+ export declare function getAuthHeaders(): Record<string, string>;
11
17
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD,qBAAa,QAAS,SAAQ,KAAK;aAGf,MAAM,EAAE,MAAM;aACd,MAAM,CAAC,EAAE,MAAM;gBAF/B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,YAAA;CAKlC"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD,qBAAa,QAAS,SAAQ,KAAK;aAGf,MAAM,EAAE,MAAM;aACd,MAAM,CAAC,EAAE,MAAM;gBAF/B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,YAAA;CAKlC;AAKD;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOvD"}
@@ -9,4 +9,19 @@ export class ApiError extends Error {
9
9
  this.name = "ApiError";
10
10
  }
11
11
  }
12
+ import { getRequestAuthHeaders } from "../auth/context.js";
13
+ import { SessionManager } from "../session/manager.js";
14
+ /**
15
+ * Returns auth headers for an API call.
16
+ * In HTTP mode (request context present): uses per-request auth from context.
17
+ * In stdio mode (no context): reads from ~/.tinify/session.json via SessionManager.
18
+ */
19
+ export function getAuthHeaders() {
20
+ // HTTP mode: context is set by the transport per request
21
+ const contextHeaders = getRequestAuthHeaders();
22
+ if (Object.keys(contextHeaders).length > 0)
23
+ return contextHeaders;
24
+ // stdio mode: read from local session file
25
+ return new SessionManager().getAuthHeaders();
26
+ }
12
27
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAExD,MAAM,OAAO,QAAS,SAAQ,KAAK;IAGf;IACA;IAHlB,YACE,OAAe,EACC,MAAc,EACd,MAAe;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,WAAM,GAAN,MAAM,CAAQ;QACd,WAAM,GAAN,MAAM,CAAS;QAG/B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAExD,MAAM,OAAO,QAAS,SAAQ,KAAK;IAGf;IACA;IAHlB,YACE,OAAe,EACC,MAAc,EACd,MAAe;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,WAAM,GAAN,MAAM,CAAQ;QACd,WAAM,GAAN,MAAM,CAAS;QAG/B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,yDAAyD;IACzD,MAAM,cAAc,GAAG,qBAAqB,EAAE,CAAC;IAC/C,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,cAAc,CAAC;IAElE,2CAA2C;IAC3C,OAAO,IAAI,cAAc,EAAE,CAAC,cAAc,EAAE,CAAC;AAC/C,CAAC"}
@@ -1,11 +1,12 @@
1
1
  export interface ProcessingSettings {
2
- output_format?: "original" | "jpg" | "png" | "webp" | "avif" | "gif";
3
- output_upscale_factor?: number;
2
+ output_format?: "original" | "jpg" | "png" | "webp" | "avif" | "gif" | "svg" | "ico";
3
+ output_upscale_factor?: 2 | 4;
4
4
  output_width?: number;
5
5
  output_height?: number;
6
6
  output_resize_behavior?: "pad" | "crop";
7
7
  output_seo_tag_gen?: boolean;
8
8
  output_seo_rename?: boolean;
9
+ output_file_size_limit?: number;
9
10
  gif_frame_limit?: number;
10
11
  }
11
12
  interface ProcessParams {
@@ -1 +1 @@
1
- {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/api/process.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,UAAU,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IACrE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sBAAsB,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,UAAU,OAAO;IACf,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAiFrF"}
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/api/process.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,UAAU,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;IACrF,qBAAqB,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sBAAsB,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,UAAU,OAAO;IACf,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAiFrF"}
@@ -1 +1 @@
1
- {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/api/process.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/api/process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Manages anonymous Supabase sessions for unauthenticated MCP clients.
3
+ * Each unique Mcp-Session-Id gets its own anonymous Supabase user.
4
+ * JWTs are cached in memory with bounded LRU eviction and TTL.
5
+ */
6
+ export declare class AnonymousSessionStore {
7
+ private readonly cache;
8
+ getOrCreate(sessionId: string): Promise<string | null>;
9
+ }
10
+ //# sourceMappingURL=anonymous.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anonymous.d.ts","sourceRoot":"","sources":["../../src/auth/anonymous.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;IAEpD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CA4B7D"}
@@ -0,0 +1,37 @@
1
+ import { createClient } from "@supabase/supabase-js";
2
+ const MAX_CACHE_SIZE = 10_000;
3
+ /**
4
+ * Manages anonymous Supabase sessions for unauthenticated MCP clients.
5
+ * Each unique Mcp-Session-Id gets its own anonymous Supabase user.
6
+ * JWTs are cached in memory with bounded LRU eviction and TTL.
7
+ */
8
+ export class AnonymousSessionStore {
9
+ cache = new Map(); // sessionId → { jwt, expiresAt }
10
+ async getOrCreate(sessionId) {
11
+ if (!process.env.SUPABASE_URL || !process.env.SUPABASE_ANON_KEY)
12
+ return null;
13
+ const cached = this.cache.get(sessionId);
14
+ if (cached && cached.expiresAt > Date.now()) {
15
+ // LRU: delete and re-insert to move to end
16
+ this.cache.delete(sessionId);
17
+ this.cache.set(sessionId, cached);
18
+ return cached.jwt;
19
+ }
20
+ // Fresh client per call to avoid race conditions between concurrent requests
21
+ const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY);
22
+ const { data, error } = await supabase.auth.signInAnonymously();
23
+ if (error || !data.session)
24
+ return null;
25
+ const jwt = data.session.access_token;
26
+ const expiresAt = Date.now() + (data.session.expires_in ?? 3600) * 1000;
27
+ // Evict oldest entry if at capacity (LRU — Map preserves insertion order)
28
+ if (this.cache.size >= MAX_CACHE_SIZE) {
29
+ const oldestKey = this.cache.keys().next().value;
30
+ if (oldestKey !== undefined)
31
+ this.cache.delete(oldestKey);
32
+ }
33
+ this.cache.set(sessionId, { jwt, expiresAt });
34
+ return jwt;
35
+ }
36
+ }
37
+ //# sourceMappingURL=anonymous.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anonymous.js","sourceRoot":"","sources":["../../src/auth/anonymous.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAOrD,MAAM,cAAc,GAAG,MAAM,CAAC;AAE9B;;;;GAIG;AACH,MAAM,OAAO,qBAAqB;IACf,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC,CAAC,iCAAiC;IAE5F,KAAK,CAAC,WAAW,CAAC,SAAiB;QACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB;YAAE,OAAO,IAAI,CAAC;QAE7E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAC5C,2CAA2C;YAC3C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAClC,OAAO,MAAM,CAAC,GAAG,CAAC;QACpB,CAAC;QAED,6EAA6E;QAC7E,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACvF,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChE,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAExC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC;QAExE,0EAA0E;QAC1E,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;YACtC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YACjD,IAAI,SAAS,KAAK,SAAS;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;QAC9C,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ interface RequestContext {
3
+ authHeaders: Record<string, string>;
4
+ sessionId: string;
5
+ }
6
+ export declare const requestContext: AsyncLocalStorage<RequestContext>;
7
+ /**
8
+ * Returns the auth headers for the currently executing MCP request.
9
+ * Returns an empty object when called outside of an HTTP request context (e.g., stdio mode).
10
+ */
11
+ export declare function getRequestAuthHeaders(): Record<string, string>;
12
+ export {};
13
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/auth/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,UAAU,cAAc;IACtB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,cAAc,mCAA0C,CAAC;AAEtE;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE9D"}
@@ -0,0 +1,10 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ export const requestContext = new AsyncLocalStorage();
3
+ /**
4
+ * Returns the auth headers for the currently executing MCP request.
5
+ * Returns an empty object when called outside of an HTTP request context (e.g., stdio mode).
6
+ */
7
+ export function getRequestAuthHeaders() {
8
+ return requestContext.getStore()?.authHeaders ?? {};
9
+ }
10
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/auth/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAOrD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,iBAAiB,EAAkB,CAAC;AAEtE;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,cAAc,CAAC,QAAQ,EAAE,EAAE,WAAW,IAAI,EAAE,CAAC;AACtD,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type JWTPayload } from "jose";
2
+ /**
3
+ * Validates a Supabase-issued JWT using JWKS.
4
+ * Returns the payload if valid, null if invalid or not a Supabase JWT.
5
+ */
6
+ export declare function verifySupabaseJwt(token: string): Promise<JWTPayload | null>;
7
+ //# sourceMappingURL=jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AActE;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAiBjF"}
@@ -0,0 +1,35 @@
1
+ import { createRemoteJWKSet, jwtVerify } from "jose";
2
+ let _jwks = null;
3
+ function getJwks() {
4
+ if (!process.env.SUPABASE_URL)
5
+ return null;
6
+ if (!_jwks) {
7
+ _jwks = createRemoteJWKSet(new URL(`${process.env.SUPABASE_URL}/auth/v1/.well-known/jwks.json`));
8
+ }
9
+ return _jwks;
10
+ }
11
+ /**
12
+ * Validates a Supabase-issued JWT using JWKS.
13
+ * Returns the payload if valid, null if invalid or not a Supabase JWT.
14
+ */
15
+ export async function verifySupabaseJwt(token) {
16
+ if (!process.env.SUPABASE_URL)
17
+ return null;
18
+ // mcp_ tokens are not JWTs; skip JWKS validation
19
+ if (!token.startsWith("eyJ"))
20
+ return null;
21
+ const jwks = getJwks();
22
+ if (!jwks)
23
+ return null;
24
+ try {
25
+ const { payload } = await jwtVerify(token, jwks, {
26
+ issuer: `${process.env.SUPABASE_URL}/auth/v1`,
27
+ audience: "authenticated",
28
+ });
29
+ return payload;
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ //# sourceMappingURL=jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAmB,MAAM,MAAM,CAAC;AAEtE,IAAI,KAAK,GAAiD,IAAI,CAAC;AAE/D,SAAS,OAAO;IACd,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG,kBAAkB,CACxB,IAAI,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,gCAAgC,CAAC,CACrE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAAa;IACnD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IAC3C,iDAAiD;IACjD,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE;YAC/C,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,UAAU;YAC7C,QAAQ,EAAE,eAAe;SAC1B,CAAC,CAAC;QACH,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Given an Authorization header value and session ID from an HTTP request,
3
+ * returns the auth headers to forward to api.tinify.ai.
4
+ *
5
+ * Priority:
6
+ * 1. Bearer mcp_... → pass through as-is (existing mcp_tokens)
7
+ * 2. Bearer eyJ... → validate Supabase JWT → pass through if valid
8
+ * 3. No/invalid auth → anonymous Supabase session JWT
9
+ */
10
+ export declare function resolveAuthHeaders(authorizationHeader: string | null, sessionId: string): Promise<Record<string, string>>;
11
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/auth/resolver.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,mBAAmB,EAAE,MAAM,GAAG,IAAI,EAClC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAqBjC"}
@@ -0,0 +1,35 @@
1
+ import { verifySupabaseJwt } from "./jwt.js";
2
+ import { AnonymousSessionStore } from "./anonymous.js";
3
+ // Module-level store — shared across all requests in this process.
4
+ const anonStore = new AnonymousSessionStore();
5
+ /**
6
+ * Given an Authorization header value and session ID from an HTTP request,
7
+ * returns the auth headers to forward to api.tinify.ai.
8
+ *
9
+ * Priority:
10
+ * 1. Bearer mcp_... → pass through as-is (existing mcp_tokens)
11
+ * 2. Bearer eyJ... → validate Supabase JWT → pass through if valid
12
+ * 3. No/invalid auth → anonymous Supabase session JWT
13
+ */
14
+ export async function resolveAuthHeaders(authorizationHeader, sessionId) {
15
+ if (authorizationHeader) {
16
+ const token = authorizationHeader.replace(/^Bearer\s+/i, "");
17
+ // mcp_ tokens: forward as-is, no validation needed here
18
+ if (token.startsWith("mcp_")) {
19
+ return { Authorization: `Bearer ${token}` };
20
+ }
21
+ // Supabase JWT: validate, then forward
22
+ if (token.startsWith("eyJ")) {
23
+ const payload = await verifySupabaseJwt(token);
24
+ if (payload)
25
+ return { Authorization: `Bearer ${token}` };
26
+ // Invalid JWT — fall through to anonymous
27
+ }
28
+ }
29
+ // No auth or invalid JWT — create/reuse anonymous session
30
+ const anonJwt = await anonStore.getOrCreate(sessionId);
31
+ if (!anonJwt)
32
+ return {};
33
+ return { Authorization: `Bearer ${anonJwt}` };
34
+ }
35
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/auth/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,mEAAmE;AACnE,MAAM,SAAS,GAAG,IAAI,qBAAqB,EAAE,CAAC;AAE9C;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,mBAAkC,EAClC,SAAiB;IAEjB,IAAI,mBAAmB,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAE7D,wDAAwD;QACxD,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC;QAC9C,CAAC;QAED,uCAAuC;QACvC,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAC/C,IAAI,OAAO;gBAAE,OAAO,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC;YACzD,0CAA0C;QAC5C,CAAC;IACH,CAAC;IAED,0DAA0D;IAC1D,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACvD,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,OAAO,EAAE,aAAa,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;AAChD,CAAC"}