@tinify-ai/mcp-server 1.3.0 → 1.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.
- package/README.md +37 -8
- package/dist/api/auth.d.ts +1 -1
- package/dist/api/auth.d.ts.map +1 -1
- package/dist/api/auth.js +2 -9
- package/dist/api/auth.js.map +1 -1
- package/dist/api/client.d.ts +6 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +15 -0
- package/dist/api/client.js.map +1 -1
- package/dist/api/process.d.ts +3 -2
- package/dist/api/process.d.ts.map +1 -1
- package/dist/api/process.js.map +1 -1
- package/dist/auth/anonymous.d.ts +10 -0
- package/dist/auth/anonymous.d.ts.map +1 -0
- package/dist/auth/anonymous.js +37 -0
- package/dist/auth/anonymous.js.map +1 -0
- package/dist/auth/context.d.ts +13 -0
- package/dist/auth/context.d.ts.map +1 -0
- package/dist/auth/context.js +10 -0
- package/dist/auth/context.js.map +1 -0
- package/dist/auth/jwt.d.ts +7 -0
- package/dist/auth/jwt.d.ts.map +1 -0
- package/dist/auth/jwt.js +35 -0
- package/dist/auth/jwt.js.map +1 -0
- package/dist/auth/resolver.d.ts +11 -0
- package/dist/auth/resolver.d.ts.map +1 -0
- package/dist/auth/resolver.js +35 -0
- package/dist/auth/resolver.js.map +1 -0
- package/dist/index.js +195 -178
- package/dist/index.js.map +1 -1
- package/dist/tools/login.js +1 -1
- package/dist/tools/login.js.map +1 -1
- package/dist/tools/optimize.d.ts +9 -2
- package/dist/tools/optimize.d.ts.map +1 -1
- package/dist/tools/optimize.js +35 -8
- package/dist/tools/optimize.js.map +1 -1
- package/dist/tools/status.d.ts.map +1 -1
- package/dist/tools/status.js +3 -6
- package/dist/tools/status.js.map +1 -1
- package/dist/transport/http.d.ts +8 -0
- package/dist/transport/http.d.ts.map +1 -0
- package/dist/transport/http.js +151 -0
- package/dist/transport/http.js.map +1 -0
- package/package.json +11 -5
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://modelcontextprotocol.io)
|
|
6
6
|
|
|
7
|
-
MCP server for [tinify.ai](https://tinify.ai) image optimization. AI-powered upscaling, resizing/cropping, compression, and SEO
|
|
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 | `
|
|
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` |
|
|
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
|
-
|
|
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
|
|
package/dist/api/auth.d.ts
CHANGED
|
@@ -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,
|
|
28
|
+
export declare function getAccountStatus(baseUrl: string, authHeaders: Record<string, string>): Promise<AccountStatus>;
|
|
29
29
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/api/auth.d.ts.map
CHANGED
|
@@ -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,
|
|
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,
|
|
29
|
-
const
|
|
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);
|
package/dist/api/auth.js.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/api/client.d.ts
CHANGED
|
@@ -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
|
package/dist/api/client.d.ts.map
CHANGED
|
@@ -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"}
|
package/dist/api/client.js
CHANGED
|
@@ -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
|
package/dist/api/client.js.map
CHANGED
|
@@ -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"}
|
package/dist/api/process.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export interface ProcessingSettings {
|
|
2
|
-
output_format?: "original" | "jpg" | "png" | "webp" | "avif" | "gif";
|
|
3
|
-
output_upscale_factor?:
|
|
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;
|
|
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"}
|
package/dist/api/process.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/api/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
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"}
|
package/dist/auth/jwt.js
ADDED
|
@@ -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"}
|