mcp-server-autoshorts 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +95 -0
  2. package/dist/catalog.d.ts +74 -0
  3. package/dist/catalog.d.ts.map +1 -0
  4. package/dist/catalog.js +95 -0
  5. package/dist/catalog.js.map +1 -0
  6. package/dist/client.d.ts +122 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +214 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/constants.d.ts +7 -0
  11. package/dist/constants.d.ts.map +1 -0
  12. package/dist/constants.js +7 -0
  13. package/dist/constants.js.map +1 -0
  14. package/dist/index.d.ts +9 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +86 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/prompts/clone-viral.d.ts +6 -0
  19. package/dist/prompts/clone-viral.d.ts.map +1 -0
  20. package/dist/prompts/clone-viral.js +33 -0
  21. package/dist/prompts/clone-viral.js.map +1 -0
  22. package/dist/prompts/generate-video.d.ts +6 -0
  23. package/dist/prompts/generate-video.d.ts.map +1 -0
  24. package/dist/prompts/generate-video.js +32 -0
  25. package/dist/prompts/generate-video.js.map +1 -0
  26. package/dist/resources/credits.d.ts +7 -0
  27. package/dist/resources/credits.d.ts.map +1 -0
  28. package/dist/resources/credits.js +16 -0
  29. package/dist/resources/credits.js.map +1 -0
  30. package/dist/resources/rate-limit.d.ts +7 -0
  31. package/dist/resources/rate-limit.d.ts.map +1 -0
  32. package/dist/resources/rate-limit.js +16 -0
  33. package/dist/resources/rate-limit.js.map +1 -0
  34. package/dist/tool-helpers.d.ts +21 -0
  35. package/dist/tool-helpers.d.ts.map +1 -0
  36. package/dist/tool-helpers.js +27 -0
  37. package/dist/tool-helpers.js.map +1 -0
  38. package/dist/tools/billing.d.ts +7 -0
  39. package/dist/tools/billing.d.ts.map +1 -0
  40. package/dist/tools/billing.js +8 -0
  41. package/dist/tools/billing.js.map +1 -0
  42. package/dist/tools/credits.d.ts +7 -0
  43. package/dist/tools/credits.d.ts.map +1 -0
  44. package/dist/tools/credits.js +8 -0
  45. package/dist/tools/credits.js.map +1 -0
  46. package/dist/tools/keys.d.ts +8 -0
  47. package/dist/tools/keys.d.ts.map +1 -0
  48. package/dist/tools/keys.js +9 -0
  49. package/dist/tools/keys.js.map +1 -0
  50. package/dist/tools/niches.d.ts +7 -0
  51. package/dist/tools/niches.d.ts.map +1 -0
  52. package/dist/tools/niches.js +8 -0
  53. package/dist/tools/niches.js.map +1 -0
  54. package/dist/tools/usage.d.ts +7 -0
  55. package/dist/tools/usage.d.ts.map +1 -0
  56. package/dist/tools/usage.js +8 -0
  57. package/dist/tools/usage.js.map +1 -0
  58. package/dist/tools/videos.d.ts +7 -0
  59. package/dist/tools/videos.d.ts.map +1 -0
  60. package/dist/tools/videos.js +75 -0
  61. package/dist/tools/videos.js.map +1 -0
  62. package/dist/types.d.ts +71 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +2 -0
  65. package/dist/types.js.map +1 -0
  66. package/package.json +36 -14
  67. package/index.js +0 -85
package/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # mcp-server-autoshorts
2
+
3
+ MCP server for [AutoShort.org](https://autoshort.org) — generate AI videos from Claude, Cursor, and other MCP clients.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npx mcp-server-autoshorts --api-key sk_live_your_key_here
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ ### Claude Desktop
14
+
15
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
16
+
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "autoshort": {
21
+ "command": "npx",
22
+ "args": ["-y", "mcp-server-autoshorts", "--api-key", "sk_live_your_key_here"]
23
+ }
24
+ }
25
+ }
26
+ ```
27
+
28
+ ### Cursor
29
+
30
+ Add to `.cursor/mcp.json`:
31
+
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "autoshort": {
36
+ "command": "npx",
37
+ "args": ["-y", "mcp-server-autoshorts", "--api-key", "sk_live_your_key_here"]
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ ### Environment Variable
44
+
45
+ Instead of `--api-key`, set `AUTOSHORT_API_KEY`:
46
+
47
+ ```bash
48
+ export AUTOSHORT_API_KEY=sk_live_your_key_here
49
+ npx mcp-server-autoshorts
50
+ ```
51
+
52
+ ## Available Tools
53
+
54
+ | Tool | Description |
55
+ |------|-------------|
56
+ | `autoshort_generate_video` | Generate an AI video from a topic |
57
+ | `autoshort_get_video` | Get video status and details |
58
+ | `autoshort_list_videos` | List your videos with pagination |
59
+ | `autoshort_list_niches` | List available niches, art styles, qualities |
60
+ | `autoshort_get_credit_balance` | Check credit balance and plan |
61
+ | `autoshort_get_usage_stats` | API usage statistics |
62
+ | `autoshort_get_subscription` | Subscription plan status |
63
+ | `autoshort_list_api_keys` | List your API keys |
64
+
65
+ Webhook tools were removed: the server does not deliver video events yet. Poll
66
+ `autoshort_get_video` every 20-30 seconds; a PENDING video that cannot render returns
67
+ `blockedReason` (for example `INSUFFICIENT_CREDITS`) instead of a countdown.
68
+
69
+ New API keys include `credits:read` and `usage:read`. A key created earlier without them gets a
70
+ 403 from `autoshort_get_credit_balance` whose message links to the page where you create a key
71
+ with that scope.
72
+
73
+ ## Resources
74
+
75
+ | URI | Description |
76
+ |-----|-------------|
77
+ | `autoshort://credits/balance` | Current credit balance |
78
+ | `autoshort://usage/rate-limit` | API rate limit status |
79
+
80
+ ## Prompts
81
+
82
+ | Name | Description |
83
+ |------|-------------|
84
+ | `generate_video` | Step-by-step video generation guide |
85
+ | `clone_viral_video` | Clone a viral video concept |
86
+
87
+ ## Get Your API Key
88
+
89
+ 1. Sign up at [autoshort.org](https://autoshort.org)
90
+ 2. Go to [Developers](https://autoshort.org/en/developers)
91
+ 3. Create an API key with desired scopes
92
+
93
+ ## License
94
+
95
+ MIT
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Values the AutoShort API accepts or charges, as this package advertises them to agents.
3
+ *
4
+ * This package is published on its own and cannot import the app, so these are copies.
5
+ * Each copy is pinned to its source by src/lib/__tests__/mcp-stdio-catalog-sync.test.ts in
6
+ * the app (VideoStatus enum, MOTION_LANGUAGE_CODES, CHAT_MESSAGE_MAX_CHARS, FEATURE_COSTS,
7
+ * VideoQuality). Change the source and that test names the line to change here. Hand-typed
8
+ * values are how the tools came to offer status GENERATING (rejected by the API), languages
9
+ * en/vi only (the API speaks nine) and "40-150 credits" (an API video costs 65).
10
+ */
11
+ /** Prisma VideoStatus, in schema order. */
12
+ export declare const VIDEO_STATUSES: readonly ["PENDING", "GENERATING_SCRIPT", "GENERATING_VOICE", "FETCHING_MEDIA", "RENDERING", "COMPLETED", "FAILED"];
13
+ /** MOTION_LANGUAGE_CODES: what POST /api/videos/chat honours as an explicit language. */
14
+ export declare const CHAT_VIDEO_LANGUAGES: readonly ["en", "es", "pt", "fr", "de", "it", "id", "tr", "vi"];
15
+ /** CHAT_MESSAGE_MAX_CHARS. */
16
+ export declare const CHAT_MESSAGE_MAX_CHARS = 4000;
17
+ /** Prisma VideoQuality. */
18
+ export declare const VIDEO_QUALITIES: readonly ["HD_720", "FULL_HD_1080"];
19
+ /** FEATURE_COSTS.video_standard and FEATURE_COSTS.voice_over_premium. */
20
+ export declare const CREDIT_COSTS: {
21
+ readonly videoStandard: 40;
22
+ readonly elevenLabsVoice: 25;
23
+ };
24
+ /** Every /api/v1 video is narrated by ElevenLabs, so the render gate asks for both. */
25
+ export declare const API_VIDEO_CREDITS: number;
26
+ export declare const API_VIDEO_COST_TEXT: string;
27
+ export declare const POLL_HINT: string;
28
+ /**
29
+ * FEATURE_COSTS.video_image_motion.
30
+ *
31
+ * Hand-copied like every other number here, and this one is the figure an agent budgets
32
+ * against BEFORE it spends: image-to-video is the only tool whose endpoint charges at submit.
33
+ * Pinned to the app constant by src/lib/__tests__/mcp-stdio-catalog-sync.test.ts.
34
+ */
35
+ export declare const IMAGE_TO_VIDEO_CREDITS = 35;
36
+ /**
37
+ * No refund promise here, deliberately.
38
+ *
39
+ * This used to say the credits are "refunded if the clip is never produced". That is not an
40
+ * invariant the pipeline holds. The operator-timeout path in cron/process-videos does call
41
+ * refundIfChargedForFailedVideo, and so does the admin refuse route — but TWO cases still end
42
+ * FAILED with money taken: that helper's own `refund-failed` outcome, and
43
+ * cron/retry-stuck-videos' permanentlyStuck `updateMany`, which has no refund call (reachable
44
+ * for one of these rows only once the operator has delivered and the render has then stalled
45
+ * MAX_RETRIES times).
46
+ *
47
+ * A longer list was checked and NARROWED: admin/videos is a GET-only dashboard whose
48
+ * `status: "FAILED"` occurrences are `where` filters, admin/videos/[id]/operator refunds
49
+ * BEFORE calling failVideo, and videos/[id]/render cannot reach its unrefunded FAILED write
50
+ * for these rows at all — that write is gated on `claimedByRequest` while every
51
+ * VEO_3_1_OPERATOR row returns ~230 lines earlier. Two real cases, not five.
52
+ *
53
+ * So the usual case refunds and the edges do not, which makes "it is refunded" a promise we
54
+ * cannot keep. Say what is true and name the check instead, so an agent that was charged for
55
+ * nothing can find out.
56
+ */
57
+ export declare const IMAGE_TO_VIDEO_COST_TEXT: string;
58
+ /**
59
+ * What an agent actually gets if the clip is fulfilled in operator mode.
60
+ *
61
+ * Image-to-video always renders through VEO_3_1_OPERATOR, which is a human driving a browser
62
+ * (scripts/veo-operator/run.mjs) — not an automatic provider. If nobody fulfils it inside the
63
+ * wait window the video FAILS. The refund wording is hedged for the reason in
64
+ * IMAGE_TO_VIDEO_COST_TEXT above; it previously claimed "any charge is refunded" flatly.
65
+ */
66
+ export declare const OPERATOR_MODE_WARNING: string;
67
+ /**
68
+ * Image-to-video dedupes on a requestId this package derives from the image bytes and the
69
+ * motion prompt — not on an Idempotency-Key header. The id carries no time component on
70
+ * purpose; the 24h bound is a continuous window on the server's lookup, so no two
71
+ * near-simultaneous retries can fall on different sides of it.
72
+ */
73
+ export declare const IMAGE_TO_VIDEO_IDEMPOTENCY_HINT: string;
74
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,2CAA2C;AAC3C,eAAO,MAAM,cAAc,qHAQjB,CAAC;AAEX,yFAAyF;AACzF,eAAO,MAAM,oBAAoB,iEAAkE,CAAC;AAEpG,8BAA8B;AAC9B,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C,2BAA2B;AAC3B,eAAO,MAAM,eAAe,qCAAsC,CAAC;AAEnE,yEAAyE;AACzE,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAEX,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,QAA4D,CAAC;AAE3F,eAAO,MAAM,mBAAmB,QAE2D,CAAC;AAE5F,eAAO,MAAM,SAAS,QAEmE,CAAC;AAE1F;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,wBAAwB,QAI8D,CAAC;AAEpG;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,QAIe,CAAC;AAElD;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,QAMsB,CAAC"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Values the AutoShort API accepts or charges, as this package advertises them to agents.
3
+ *
4
+ * This package is published on its own and cannot import the app, so these are copies.
5
+ * Each copy is pinned to its source by src/lib/__tests__/mcp-stdio-catalog-sync.test.ts in
6
+ * the app (VideoStatus enum, MOTION_LANGUAGE_CODES, CHAT_MESSAGE_MAX_CHARS, FEATURE_COSTS,
7
+ * VideoQuality). Change the source and that test names the line to change here. Hand-typed
8
+ * values are how the tools came to offer status GENERATING (rejected by the API), languages
9
+ * en/vi only (the API speaks nine) and "40-150 credits" (an API video costs 65).
10
+ */
11
+ /** Prisma VideoStatus, in schema order. */
12
+ export const VIDEO_STATUSES = [
13
+ 'PENDING',
14
+ 'GENERATING_SCRIPT',
15
+ 'GENERATING_VOICE',
16
+ 'FETCHING_MEDIA',
17
+ 'RENDERING',
18
+ 'COMPLETED',
19
+ 'FAILED',
20
+ ];
21
+ /** MOTION_LANGUAGE_CODES: what POST /api/videos/chat honours as an explicit language. */
22
+ export const CHAT_VIDEO_LANGUAGES = ['en', 'es', 'pt', 'fr', 'de', 'it', 'id', 'tr', 'vi'];
23
+ /** CHAT_MESSAGE_MAX_CHARS. */
24
+ export const CHAT_MESSAGE_MAX_CHARS = 4000;
25
+ /** Prisma VideoQuality. */
26
+ export const VIDEO_QUALITIES = ['HD_720', 'FULL_HD_1080'];
27
+ /** FEATURE_COSTS.video_standard and FEATURE_COSTS.voice_over_premium. */
28
+ export const CREDIT_COSTS = {
29
+ videoStandard: 40,
30
+ elevenLabsVoice: 25,
31
+ };
32
+ /** Every /api/v1 video is narrated by ElevenLabs, so the render gate asks for both. */
33
+ export const API_VIDEO_CREDITS = CREDIT_COSTS.videoStandard + CREDIT_COSTS.elevenLabsVoice;
34
+ export const API_VIDEO_COST_TEXT = `Costs ${API_VIDEO_CREDITS} credits (${CREDIT_COSTS.videoStandard} render + ` +
35
+ `${CREDIT_COSTS.elevenLabsVoice} ElevenLabs voice); art style does not change the price.`;
36
+ export const POLL_HINT = 'Rendering is asynchronous: poll autoshort_get_video every 20-30 seconds until status is COMPLETED or FAILED. ' +
37
+ 'If get_video returns blockedReason, stop polling and act on it (e.g. top up credits).';
38
+ /**
39
+ * FEATURE_COSTS.video_image_motion.
40
+ *
41
+ * Hand-copied like every other number here, and this one is the figure an agent budgets
42
+ * against BEFORE it spends: image-to-video is the only tool whose endpoint charges at submit.
43
+ * Pinned to the app constant by src/lib/__tests__/mcp-stdio-catalog-sync.test.ts.
44
+ */
45
+ export const IMAGE_TO_VIDEO_CREDITS = 35;
46
+ /**
47
+ * No refund promise here, deliberately.
48
+ *
49
+ * This used to say the credits are "refunded if the clip is never produced". That is not an
50
+ * invariant the pipeline holds. The operator-timeout path in cron/process-videos does call
51
+ * refundIfChargedForFailedVideo, and so does the admin refuse route — but TWO cases still end
52
+ * FAILED with money taken: that helper's own `refund-failed` outcome, and
53
+ * cron/retry-stuck-videos' permanentlyStuck `updateMany`, which has no refund call (reachable
54
+ * for one of these rows only once the operator has delivered and the render has then stalled
55
+ * MAX_RETRIES times).
56
+ *
57
+ * A longer list was checked and NARROWED: admin/videos is a GET-only dashboard whose
58
+ * `status: "FAILED"` occurrences are `where` filters, admin/videos/[id]/operator refunds
59
+ * BEFORE calling failVideo, and videos/[id]/render cannot reach its unrefunded FAILED write
60
+ * for these rows at all — that write is gated on `claimedByRequest` while every
61
+ * VEO_3_1_OPERATOR row returns ~230 lines earlier. Two real cases, not five.
62
+ *
63
+ * So the usual case refunds and the edges do not, which makes "it is refunded" a promise we
64
+ * cannot keep. Say what is true and name the check instead, so an agent that was charged for
65
+ * nothing can find out.
66
+ */
67
+ export const IMAGE_TO_VIDEO_COST_TEXT = `Costs ${IMAGE_TO_VIDEO_CREDITS} credits, and unlike every other tool here it is charged ` +
68
+ 'the moment the job is accepted, not when the clip is delivered. A failed clip is normally ' +
69
+ 'refunded automatically, but that is not guaranteed on every failure path: if the video ends ' +
70
+ 'FAILED, check autoshort_get_credit_balance and report a missing refund rather than assuming it.';
71
+ /**
72
+ * What an agent actually gets if the clip is fulfilled in operator mode.
73
+ *
74
+ * Image-to-video always renders through VEO_3_1_OPERATOR, which is a human driving a browser
75
+ * (scripts/veo-operator/run.mjs) — not an automatic provider. If nobody fulfils it inside the
76
+ * wait window the video FAILS. The refund wording is hedged for the reason in
77
+ * IMAGE_TO_VIDEO_COST_TEXT above; it previously claimed "any charge is refunded" flatly.
78
+ */
79
+ export const OPERATOR_MODE_WARNING = 'Fulfilment is MANUAL: a human operator animates the image, it is not an automatic render. ' +
80
+ 'If nobody fulfils it within VEO_OPERATOR_WAIT_MINUTES (10 in production) the video FAILS ' +
81
+ 'with "could not be produced in time" and the charge is normally refunded automatically. ' +
82
+ 'Do not build an unattended loop on this tool.';
83
+ /**
84
+ * Image-to-video dedupes on a requestId this package derives from the image bytes and the
85
+ * motion prompt — not on an Idempotency-Key header. The id carries no time component on
86
+ * purpose; the 24h bound is a continuous window on the server's lookup, so no two
87
+ * near-simultaneous retries can fall on different sides of it.
88
+ */
89
+ export const IMAGE_TO_VIDEO_IDEMPOTENCY_HINT = 'Retry-safe: re-calling with the same image and motionPrompt returns the first job ' +
90
+ '(duplicate: true) for 24 hours instead of charging again. If that attempt FAILED, a retry ' +
91
+ 'refunds the dead attempt first and then makes a new clip, so one clip is never billed ' +
92
+ 'twice — whatever its age. In the one case where the old credits cannot be returned you get ' +
93
+ '409 STRANDED_CHARGE with the videoId and no new charge: report it, do not loop. Pass ' +
94
+ 'idempotencyKey to force a separate clip from identical inputs.';
95
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,2CAA2C;AAC3C,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,SAAS;IACT,mBAAmB;IACnB,kBAAkB;IAClB,gBAAgB;IAChB,WAAW;IACX,WAAW;IACX,QAAQ;CACA,CAAC;AAEX,yFAAyF;AACzF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;AAEpG,8BAA8B;AAC9B,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C,2BAA2B;AAC3B,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAU,CAAC;AAEnE,yEAAyE;AACzE,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,aAAa,EAAE,EAAE;IACjB,eAAe,EAAE,EAAE;CACX,CAAC;AAEX,uFAAuF;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,CAAC,aAAa,GAAG,YAAY,CAAC,eAAe,CAAC;AAE3F,MAAM,CAAC,MAAM,mBAAmB,GAC9B,SAAS,iBAAiB,aAAa,YAAY,CAAC,aAAa,YAAY;IAC7E,GAAG,YAAY,CAAC,eAAe,0DAA0D,CAAC;AAE5F,MAAM,CAAC,MAAM,SAAS,GACpB,+GAA+G;IAC/G,uFAAuF,CAAC;AAE1F;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,wBAAwB,GACnC,SAAS,sBAAsB,2DAA2D;IAC1F,4FAA4F;IAC5F,8FAA8F;IAC9F,iGAAiG,CAAC;AAEpG;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAChC,4FAA4F;IAC5F,2FAA2F;IAC3F,0FAA0F;IAC1F,+CAA+C,CAAC;AAElD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAC1C,oFAAoF;IACpF,4FAA4F;IAC5F,wFAAwF;IACxF,6FAA6F;IAC7F,uFAAuF;IACvF,gEAAgE,CAAC"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * AutoShort API HTTP Client
3
+ *
4
+ * Wraps all v1 API endpoints with typed methods.
5
+ * Captures rate limit headers for MCP resource exposure.
6
+ */
7
+ import type { RateLimitInfo } from './types.js';
8
+ export declare class AutoShortClient {
9
+ private readonly apiKey;
10
+ private readonly baseUrl;
11
+ /** Last rate limit info from API response headers */
12
+ lastRateLimit: RateLimitInfo | null;
13
+ constructor(apiKey: string, baseUrl: string);
14
+ /** Generic API request with auth, error handling, rate limit capture */
15
+ request<T>(method: string, path: string, body?: unknown): Promise<T>;
16
+ generateVideo(params: {
17
+ topic: string;
18
+ niche?: string;
19
+ duration?: number;
20
+ artStyle?: string;
21
+ quality?: string;
22
+ }): Promise<{
23
+ id: string;
24
+ status: string;
25
+ }>;
26
+ generateChatVideo(params: {
27
+ message: string;
28
+ videoProvider?: 'FFMPEG' | 'VEO_3_1_OPERATOR';
29
+ artStyle?: string;
30
+ aspectRatio?: '9:16' | '1:1' | '16:9';
31
+ language?: string;
32
+ targetDuration?: number;
33
+ }): Promise<{
34
+ videoId: string;
35
+ reply: string;
36
+ params: Record<string, unknown>;
37
+ }>;
38
+ generateProductAd(params: {
39
+ url: string;
40
+ language?: string;
41
+ artStyle?: string;
42
+ duration?: number;
43
+ }): Promise<Record<string, unknown>>;
44
+ generateImageToVideo(params: {
45
+ imagePath: string;
46
+ motionPrompt: string;
47
+ idempotencyKey?: string;
48
+ }): Promise<Record<string, unknown>>;
49
+ getVideo(id: string): Promise<Record<string, unknown>>;
50
+ listVideos(params?: {
51
+ limit?: number;
52
+ offset?: number;
53
+ status?: string;
54
+ }): Promise<{
55
+ videos: unknown[];
56
+ pagination: unknown;
57
+ }>;
58
+ listNiches(): Promise<{
59
+ niches: unknown[];
60
+ artStyles: unknown[];
61
+ videoQualities: unknown[];
62
+ durations: number[];
63
+ }>;
64
+ getCreditBalance(): Promise<{
65
+ balance: number;
66
+ monthlyAllocation: number;
67
+ bonusCredits: number;
68
+ plan: string;
69
+ }>;
70
+ getUsageStats(): Promise<Record<string, unknown>>;
71
+ getSubscription(): Promise<Record<string, unknown>>;
72
+ listApiKeys(): Promise<{
73
+ apiKeys: unknown[];
74
+ }>;
75
+ }
76
+ /** Typed API error with HTTP status and error code */
77
+ export declare class AutoShortApiError extends Error {
78
+ readonly status: number;
79
+ readonly code: string;
80
+ constructor(message: string, status: number, code: string);
81
+ }
82
+ /**
83
+ * MIME from the file's own first bytes, with the extension only as a tiebreaker.
84
+ *
85
+ * It used to be derived from the extension alone, so an extensionless file, a `.jfif` or a
86
+ * `.gif` was declared `image/jpeg` and failed the server's magic-byte check with the unhelpful
87
+ * "Image contents do not match the uploaded file type" / "Invalid image data". Sniffing means a
88
+ * correct file is labelled correctly whatever it is called, and a genuinely unsupported format
89
+ * keeps its real type so the server's 400 names the actual problem.
90
+ */
91
+ export declare function sniffImageMime(bytes: Uint8Array, imagePath: string): string;
92
+ /**
93
+ * Shape a deterministic hash into something the route's STRICT v4 regex accepts.
94
+ *
95
+ * `requestId` is validated against
96
+ * /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i, so a bare sha256
97
+ * is refused with 400 "A valid request ID is required". Version nibble pinned to 4 and the
98
+ * variant nibble forced into 8..b; every other nibble comes from the hash.
99
+ */
100
+ export declare function uuidFromSeed(seed: string): string;
101
+ /**
102
+ * The request id for one image-to-video submission: deterministic, and ALWAYS content-bound.
103
+ *
104
+ * Two rules, each closing a way of being charged 35 credits twice.
105
+ *
106
+ * 1. NO CLOCK IN THE SEED. It used to be `randomUUID()` per call, which defeats all three of
107
+ * the endpoint's dedupe layers (pre-check, pg_advisory_xact_lock, in-transaction re-check)
108
+ * and buys a second clip on every retry. A later attempt salted the seed with a UTC day
109
+ * bucket, which is worse than it looks: a bucket has an edge, so a retry at 23:59:59 and
110
+ * its follow-up at 00:00:01 derive DIFFERENT ids and miss every layer. The time bound
111
+ * belongs on the READER, as a continuous window — see imageToVideoDedupeSince() in
112
+ * src/lib/image-to-video-policy.ts.
113
+ *
114
+ * 2. THE CONTENT IS ALWAYS IN THE SEED, even when the caller supplies a key. A caller key used
115
+ * to replace the content seed outright, so an agent passing one run-scoped key for two
116
+ * different clips got the FIRST video back for the second ask — `duplicate: true`, no
117
+ * fingerprint compared, so not even a 422 to tell it apart. Folding both in keeps each
118
+ * direction working: a distinct key separates two deliberate clips from identical inputs,
119
+ * and distinct inputs separate two clips that happen to share a key.
120
+ */
121
+ export declare function imageToVideoRequestId(imageBytes: Uint8Array, motionPrompt: string, idempotencyKey?: string): string;
122
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKhD,qBAAa,eAAe;IAKxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL1B,qDAAqD;IAC9C,aAAa,EAAE,aAAa,GAAG,IAAI,CAAQ;gBAG/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;IAGlC,wEAAwE;IAClE,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAqCpE,aAAa,CAAC,MAAM,EAAE;QAC1B,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;KACrC;YAC2B,MAAM;gBAAU,MAAM;;IAG5C,iBAAiB,CAAC,MAAM,EAAE;QAC9B,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,QAAQ,GAAG,kBAAkB,CAAC;QAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;QACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC;KAC5C;iBACgC,MAAM;eAAS,MAAM;gBAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;IAKjF,iBAAiB,CAAC,MAAM,EAAE;QAC9B,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;KACtE;IAIK,oBAAoB,CAAC,MAAM,EAAE;QACjC,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB;IAgCK,QAAQ,CAAC,EAAE,EAAE,MAAM;IAInB,UAAU,CAAC,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;gBAI9C,OAAO,EAAE;oBAAc,OAAO;;IAKxD,UAAU;gBACgB,OAAO,EAAE;mBAAa,OAAO,EAAE;wBAAkB,OAAO,EAAE;mBAAa,MAAM,EAAE;;IAOzG,gBAAgB;iBACW,MAAM;2BAAqB,MAAM;sBAAgB,MAAM;cAAQ,MAAM;;IAOhG,aAAa;IAMb,eAAe;IAMf,WAAW;iBACgB,OAAO,EAAE;;CAE3C;AAED,sDAAsD;AACtD,qBAAa,iBAAkB,SAAQ,KAAK;aAGxB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;gBAF5B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM;CAK/B;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAqB3E;AAID;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOjD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CAWR"}
package/dist/client.js ADDED
@@ -0,0 +1,214 @@
1
+ /**
2
+ * AutoShort API HTTP Client
3
+ *
4
+ * Wraps all v1 API endpoints with typed methods.
5
+ * Captures rate limit headers for MCP resource exposure.
6
+ */
7
+ import { USER_AGENT } from './constants.js';
8
+ import { readFile } from 'node:fs/promises';
9
+ import { basename, extname } from 'node:path';
10
+ import { createHash } from 'node:crypto';
11
+ export class AutoShortClient {
12
+ apiKey;
13
+ baseUrl;
14
+ /** Last rate limit info from API response headers */
15
+ lastRateLimit = null;
16
+ constructor(apiKey, baseUrl) {
17
+ this.apiKey = apiKey;
18
+ this.baseUrl = baseUrl;
19
+ }
20
+ /** Generic API request with auth, error handling, rate limit capture */
21
+ async request(method, path, body) {
22
+ const url = `${this.baseUrl}${path}`;
23
+ const res = await fetch(url, {
24
+ method,
25
+ headers: {
26
+ 'Authorization': `Bearer ${this.apiKey}`,
27
+ 'Content-Type': 'application/json',
28
+ 'User-Agent': USER_AGENT,
29
+ },
30
+ body: body ? JSON.stringify(body) : undefined,
31
+ });
32
+ // Capture rate limit headers
33
+ const limit = res.headers.get('x-ratelimit-limit');
34
+ const remaining = res.headers.get('x-ratelimit-remaining');
35
+ const resetAt = res.headers.get('x-ratelimit-reset');
36
+ if (limit && remaining && resetAt) {
37
+ this.lastRateLimit = {
38
+ limit: parseInt(limit),
39
+ remaining: parseInt(remaining),
40
+ resetAt,
41
+ };
42
+ }
43
+ if (!res.ok) {
44
+ let errorBody = {};
45
+ try {
46
+ errorBody = await res.json();
47
+ }
48
+ catch { /* empty */ }
49
+ const msg = errorBody.error || `API error: ${res.status} ${res.statusText}`;
50
+ const code = errorBody.code || `HTTP_${res.status}`;
51
+ throw new AutoShortApiError(msg, res.status, code);
52
+ }
53
+ return res.json();
54
+ }
55
+ // ── Video endpoints ──
56
+ async generateVideo(params) {
57
+ return this.request('POST', '/api/v1/videos/generate', params);
58
+ }
59
+ async generateChatVideo(params) {
60
+ return this.request('POST', '/api/videos/chat', params);
61
+ }
62
+ async generateProductAd(params) {
63
+ return this.request('POST', '/api/videos/product-ad', params);
64
+ }
65
+ async generateImageToVideo(params) {
66
+ const bytes = await readFile(params.imagePath);
67
+ const form = new FormData();
68
+ form.set('image', new Blob([bytes], { type: sniffImageMime(bytes, params.imagePath) }), basename(params.imagePath));
69
+ form.set('motionPrompt', params.motionPrompt);
70
+ // NO `provider` field, deliberately.
71
+ //
72
+ // The route reads `String(form.get("provider") || IMAGE_TO_VIDEO_POLICY.provider)`, so an
73
+ // absent field already resolves to the one token it accepts. We used to send
74
+ // 'VEO_3_1_OPERATOR' — the endpoint's internal RENDER provider, not its submission token —
75
+ // and so EVERY call came back 400 "Image to Video uses its own flow only; direct Veo API is
76
+ // disabled" (reproduced against production 2026-10-16). Hardcoding the correct literal here
77
+ // would fix today's call and re-couple this standalone package to a server constant it
78
+ // cannot import; omitting the field lets the server own its own default.
79
+ form.set('requestId', imageToVideoRequestId(bytes, params.motionPrompt, params.idempotencyKey));
80
+ const res = await fetch(`${this.baseUrl}/api/videos/image-to-video`, {
81
+ method: 'POST',
82
+ headers: { 'Authorization': `Bearer ${this.apiKey}`, 'User-Agent': USER_AGENT },
83
+ body: form,
84
+ });
85
+ if (!res.ok) {
86
+ const body = await res.json().catch(() => ({}));
87
+ throw new AutoShortApiError(body.error || `API error: ${res.status}`, res.status, `HTTP_${res.status}`);
88
+ }
89
+ return res.json();
90
+ }
91
+ async getVideo(id) {
92
+ return this.request('GET', `/api/v1/videos/${encodeURIComponent(id)}`);
93
+ }
94
+ async listVideos(params) {
95
+ const qs = params ? '?' + new URLSearchParams(Object.entries(params).filter(([, v]) => v != null).map(([k, v]) => [k, String(v)])).toString() : '';
96
+ return this.request('GET', `/api/v1/videos${qs}`);
97
+ }
98
+ // ── Niches ──
99
+ async listNiches() {
100
+ return this.request('GET', '/api/v1/scripts/niches');
101
+ }
102
+ // ── Credits ──
103
+ async getCreditBalance() {
104
+ return this.request('GET', '/api/v1/credits/balance');
105
+ }
106
+ // ── Usage ──
107
+ async getUsageStats() {
108
+ return this.request('GET', '/api/v1/usage/stats');
109
+ }
110
+ // ── Billing ──
111
+ async getSubscription() {
112
+ return this.request('GET', '/api/v1/billing/subscription');
113
+ }
114
+ // ── API Keys ──
115
+ async listApiKeys() {
116
+ return this.request('GET', '/api/v1/keys');
117
+ }
118
+ }
119
+ /** Typed API error with HTTP status and error code */
120
+ export class AutoShortApiError extends Error {
121
+ status;
122
+ code;
123
+ constructor(message, status, code) {
124
+ super(message);
125
+ this.status = status;
126
+ this.code = code;
127
+ this.name = 'AutoShortApiError';
128
+ }
129
+ }
130
+ /**
131
+ * MIME from the file's own first bytes, with the extension only as a tiebreaker.
132
+ *
133
+ * It used to be derived from the extension alone, so an extensionless file, a `.jfif` or a
134
+ * `.gif` was declared `image/jpeg` and failed the server's magic-byte check with the unhelpful
135
+ * "Image contents do not match the uploaded file type" / "Invalid image data". Sniffing means a
136
+ * correct file is labelled correctly whatever it is called, and a genuinely unsupported format
137
+ * keeps its real type so the server's 400 names the actual problem.
138
+ */
139
+ export function sniffImageMime(bytes, imagePath) {
140
+ const b = bytes;
141
+ if (b.length >= 3 && b[0] === 0xff && b[1] === 0xd8 && b[2] === 0xff)
142
+ return 'image/jpeg';
143
+ if (b.length >= 8 &&
144
+ b[0] === 0x89 && b[1] === 0x50 && b[2] === 0x4e && b[3] === 0x47 &&
145
+ b[4] === 0x0d && b[5] === 0x0a && b[6] === 0x1a && b[7] === 0x0a)
146
+ return 'image/png';
147
+ if (b.length >= 12 &&
148
+ String.fromCharCode(b[0], b[1], b[2], b[3]) === 'RIFF' &&
149
+ String.fromCharCode(b[8], b[9], b[10], b[11]) === 'WEBP')
150
+ return 'image/webp';
151
+ if (b.length >= 6 && String.fromCharCode(b[0], b[1], b[2]) === 'GIF')
152
+ return 'image/gif';
153
+ // Unrecognised: fall back to the extension so the server's refusal names a real type rather
154
+ // than one we invented.
155
+ const extension = extname(imagePath).toLowerCase();
156
+ if (extension === '.png')
157
+ return 'image/png';
158
+ if (extension === '.webp')
159
+ return 'image/webp';
160
+ if (extension === '.gif')
161
+ return 'image/gif';
162
+ return 'application/octet-stream';
163
+ }
164
+ const UUID_V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
165
+ /**
166
+ * Shape a deterministic hash into something the route's STRICT v4 regex accepts.
167
+ *
168
+ * `requestId` is validated against
169
+ * /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i, so a bare sha256
170
+ * is refused with 400 "A valid request ID is required". Version nibble pinned to 4 and the
171
+ * variant nibble forced into 8..b; every other nibble comes from the hash.
172
+ */
173
+ export function uuidFromSeed(seed) {
174
+ const h = createHash('sha256').update(seed).digest('hex');
175
+ const variant = ((parseInt(h[16], 16) & 0x3) | 0x8).toString(16);
176
+ const id = `${h.slice(0, 8)}-${h.slice(8, 12)}-4${h.slice(13, 16)}-${variant}${h.slice(17, 20)}-${h.slice(20, 32)}`;
177
+ /* c8 ignore next */
178
+ if (!UUID_V4.test(id))
179
+ throw new Error(`derived request id is not a v4 UUID: ${id}`);
180
+ return id;
181
+ }
182
+ /**
183
+ * The request id for one image-to-video submission: deterministic, and ALWAYS content-bound.
184
+ *
185
+ * Two rules, each closing a way of being charged 35 credits twice.
186
+ *
187
+ * 1. NO CLOCK IN THE SEED. It used to be `randomUUID()` per call, which defeats all three of
188
+ * the endpoint's dedupe layers (pre-check, pg_advisory_xact_lock, in-transaction re-check)
189
+ * and buys a second clip on every retry. A later attempt salted the seed with a UTC day
190
+ * bucket, which is worse than it looks: a bucket has an edge, so a retry at 23:59:59 and
191
+ * its follow-up at 00:00:01 derive DIFFERENT ids and miss every layer. The time bound
192
+ * belongs on the READER, as a continuous window — see imageToVideoDedupeSince() in
193
+ * src/lib/image-to-video-policy.ts.
194
+ *
195
+ * 2. THE CONTENT IS ALWAYS IN THE SEED, even when the caller supplies a key. A caller key used
196
+ * to replace the content seed outright, so an agent passing one run-scoped key for two
197
+ * different clips got the FIRST video back for the second ask — `duplicate: true`, no
198
+ * fingerprint compared, so not even a 422 to tell it apart. Folding both in keeps each
199
+ * direction working: a distinct key separates two deliberate clips from identical inputs,
200
+ * and distinct inputs separate two clips that happen to share a key.
201
+ */
202
+ export function imageToVideoRequestId(imageBytes, motionPrompt, idempotencyKey) {
203
+ // TRIMMED, to match what the server stores and dedupes on.
204
+ //
205
+ // The route does `String(form.get("motionPrompt") || "").trim()`, so it treats "push in" and
206
+ // "push in " as the same prompt. Hashing the raw string here did not: the two derived
207
+ // DIFFERENT requestIds, missed all three server dedupe layers, and bought two 35-credit
208
+ // charges for two identical clips. An agent replaying a retry with whitespace drift is the
209
+ // realistic caller. Any normalization the server applies has to be applied here too, or the
210
+ // derived id stops being a function of what the server actually keys on.
211
+ const content = `${createHash('sha256').update(imageBytes).digest('hex')}:${motionPrompt.trim()}`;
212
+ return uuidFromSeed(idempotencyKey ? `${idempotencyKey}\u0000${content}` : content);
213
+ }
214
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /** Default AutoShort API base URL */
2
+ export declare const DEFAULT_BASE_URL = "https://autoshort.org";
3
+ /** MCP server version */
4
+ export declare const VERSION = "2.0.0";
5
+ /** User-Agent header for API requests */
6
+ export declare const USER_AGENT = "autoshort-mcp-server/2.0.0";
7
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD,yBAAyB;AACzB,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,yCAAyC;AACzC,eAAO,MAAM,UAAU,+BAAoC,CAAC"}
@@ -0,0 +1,7 @@
1
+ /** Default AutoShort API base URL */
2
+ export const DEFAULT_BASE_URL = 'https://autoshort.org';
3
+ /** MCP server version */
4
+ export const VERSION = '2.0.0'; // 2.0.0: webhook tools and the webhookUrl param removed
5
+ /** User-Agent header for API requests */
6
+ export const USER_AGENT = `autoshort-mcp-server/${VERSION}`;
7
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,MAAM,CAAC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAExD,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,wDAAwD;AAExF,yCAAyC;AACzC,MAAM,CAAC,MAAM,UAAU,GAAG,wBAAwB,OAAO,EAAE,CAAC"}