@mixio-pro/kalaasetu-mcp 1.2.2 → 2.0.2-beta
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/fal-config.json +106 -0
- package/package.json +2 -1
- package/src/index.ts +5 -9
- package/src/tools/fal/config.ts +120 -23
- package/src/tools/fal/generate.ts +361 -103
- package/src/tools/fal/index.ts +2 -7
- package/src/tools/fal/models.ts +157 -32
- package/src/tools/gemini.ts +40 -2
- package/src/tools/get-status.ts +174 -0
- package/src/tools/image-to-video.ts +334 -119
- package/src/utils/llm-prompt-enhancer.ts +302 -0
- package/src/utils/prompt-enhancer-presets.ts +303 -0
- package/src/utils/prompt-enhancer.ts +186 -0
package/fal-config.json
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"presets": [
|
|
3
|
+
{
|
|
4
|
+
"presetName": "ltx_image_to_video",
|
|
5
|
+
"intent": "Generate high-quality cinematic video with audio from a static image using LTX Video 2.0 Pro.",
|
|
6
|
+
"modelId": "fal-ai/ltx-2/image-to-video",
|
|
7
|
+
"inputType": "image",
|
|
8
|
+
"outputType": "video",
|
|
9
|
+
"promptEnhancer": "ltx2",
|
|
10
|
+
"input_schema": {
|
|
11
|
+
"prompt": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "The prompt to generate the video from",
|
|
14
|
+
"example": "A woman stands still amid a busy neon-lit street at night. The camera slowly dollies in toward her face as people blur past, their motion emphasizing her calm presence. City lights flicker and reflections shift across her denim jacket."
|
|
15
|
+
},
|
|
16
|
+
"resolution": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "The resolution of the generated video",
|
|
19
|
+
"enum": [
|
|
20
|
+
"1080p",
|
|
21
|
+
"1440p",
|
|
22
|
+
"2160p"
|
|
23
|
+
],
|
|
24
|
+
"default": "1080p"
|
|
25
|
+
},
|
|
26
|
+
"aspect_ratio": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"description": "The aspect ratio of the generated video",
|
|
29
|
+
"enum": [
|
|
30
|
+
"16:9"
|
|
31
|
+
],
|
|
32
|
+
"default": "16:9"
|
|
33
|
+
},
|
|
34
|
+
"generate_audio": {
|
|
35
|
+
"type": "boolean",
|
|
36
|
+
"description": "Whether to generate audio for the generated video",
|
|
37
|
+
"default": true
|
|
38
|
+
},
|
|
39
|
+
"duration": {
|
|
40
|
+
"type": "integer",
|
|
41
|
+
"description": "The duration of the generated video in seconds",
|
|
42
|
+
"enum": [
|
|
43
|
+
6,
|
|
44
|
+
8,
|
|
45
|
+
10
|
|
46
|
+
],
|
|
47
|
+
"default": 6
|
|
48
|
+
},
|
|
49
|
+
"fps": {
|
|
50
|
+
"type": "integer",
|
|
51
|
+
"description": "The frames per second of the generated video",
|
|
52
|
+
"enum": [
|
|
53
|
+
25,
|
|
54
|
+
50
|
|
55
|
+
],
|
|
56
|
+
"default": 25
|
|
57
|
+
},
|
|
58
|
+
"image_url": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"description": "URL of the image to generate the video from. Must be publicly accessible or base64 data URI. Supports PNG, JPEG, WebP, AVIF, and HEIF formats.",
|
|
61
|
+
"example": "https://storage.googleapis.com/falserverless/example_inputs/ltxv-2-i2v-input.jpg"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"presetName": "ltx_retake_video",
|
|
67
|
+
"intent": "Perform selective video editing and targetted alterations on existing videos using LTX-2.",
|
|
68
|
+
"modelId": "fal-ai/ltx-2/retake-video",
|
|
69
|
+
"inputType": "video",
|
|
70
|
+
"outputType": "video",
|
|
71
|
+
"promptEnhancer": "ltx2",
|
|
72
|
+
"input_schema": {
|
|
73
|
+
"prompt": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"description": "The prompt to retake the video with",
|
|
76
|
+
"example": "Remove the man"
|
|
77
|
+
},
|
|
78
|
+
"duration": {
|
|
79
|
+
"type": "number",
|
|
80
|
+
"description": "The duration of the video to retake in seconds",
|
|
81
|
+
"default": 5
|
|
82
|
+
},
|
|
83
|
+
"start_time": {
|
|
84
|
+
"type": "number",
|
|
85
|
+
"description": "The start time of the video to retake in seconds",
|
|
86
|
+
"default": 0
|
|
87
|
+
},
|
|
88
|
+
"video_url": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"description": "The URL of the video to retake",
|
|
91
|
+
"example": "https://v3b.fal.media/files/b/kangaroo/409mvS2FMwb6S7WcwkSW7_output.mp4"
|
|
92
|
+
},
|
|
93
|
+
"retake_mode": {
|
|
94
|
+
"type": "string",
|
|
95
|
+
"description": "The retake mode to use for the retake",
|
|
96
|
+
"enum": [
|
|
97
|
+
"replace_audio",
|
|
98
|
+
"replace_video",
|
|
99
|
+
"replace_audio_and_video"
|
|
100
|
+
],
|
|
101
|
+
"default": "replace_audio_and_video"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mixio-pro/kalaasetu-mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.2-beta",
|
|
4
4
|
"description": "A powerful Model Context Protocol server providing AI tools for content generation and analysis",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"src",
|
|
13
13
|
"bin",
|
|
14
|
+
"fal-config.json",
|
|
14
15
|
"README.md",
|
|
15
16
|
"LICENSE"
|
|
16
17
|
],
|
package/src/index.ts
CHANGED
|
@@ -6,11 +6,7 @@ import { imageToVideo } from "./tools/image-to-video";
|
|
|
6
6
|
import {
|
|
7
7
|
falListPresets,
|
|
8
8
|
falGetPresetDetails,
|
|
9
|
-
falGetConfig,
|
|
10
9
|
falGenerate,
|
|
11
|
-
falGetResult,
|
|
12
|
-
falGetStatus,
|
|
13
|
-
falCancelRequest,
|
|
14
10
|
falUploadFile,
|
|
15
11
|
} from "./tools/fal";
|
|
16
12
|
|
|
@@ -40,16 +36,16 @@ server.addTool(imageToVideo);
|
|
|
40
36
|
// server.addTool(perplexityImages);
|
|
41
37
|
// server.addTool(perplexityVideos);
|
|
42
38
|
|
|
39
|
+
import { getGenerationStatus } from "./tools/get-status";
|
|
40
|
+
|
|
43
41
|
// Fal AI Tools
|
|
44
|
-
server.addTool(falGetConfig);
|
|
45
42
|
server.addTool(falListPresets);
|
|
46
|
-
server.addTool(falGetPresetDetails);
|
|
47
43
|
server.addTool(falGenerate);
|
|
48
|
-
server.addTool(falGetResult);
|
|
49
|
-
server.addTool(falGetStatus);
|
|
50
|
-
server.addTool(falCancelRequest);
|
|
51
44
|
server.addTool(falUploadFile);
|
|
52
45
|
|
|
46
|
+
// Unified Status Tool (works with both FAL and Vertex AI)
|
|
47
|
+
server.addTool(getGenerationStatus);
|
|
48
|
+
|
|
53
49
|
server.start({
|
|
54
50
|
transportType: "stdio",
|
|
55
51
|
});
|
package/src/tools/fal/config.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import * as fs from "fs";
|
|
5
5
|
import * as path from "path";
|
|
6
|
+
import type { PromptEnhancerConfig } from "../../utils/prompt-enhancer";
|
|
6
7
|
|
|
7
8
|
// API URLs
|
|
8
9
|
export const FAL_BASE_URL = "https://fal.ai/api";
|
|
@@ -45,6 +46,10 @@ export interface FalPresetConfig {
|
|
|
45
46
|
defaultParams?: Record<string, any>;
|
|
46
47
|
inputType?: "text" | "image" | "video" | "audio" | "custom";
|
|
47
48
|
outputType?: "image" | "video" | "audio" | "text" | "custom";
|
|
49
|
+
/** Optional prompt enhancer: preset name (string) or inline config */
|
|
50
|
+
promptEnhancer?: string | PromptEnhancerConfig;
|
|
51
|
+
/** Optional JSON schema for the model's input parameters */
|
|
52
|
+
input_schema?: Record<string, any>;
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
/**
|
|
@@ -59,31 +64,68 @@ export interface FalConfig {
|
|
|
59
64
|
*/
|
|
60
65
|
export const DEFAULT_PRESETS: FalPresetConfig[] = [
|
|
61
66
|
{
|
|
62
|
-
presetName: "
|
|
63
|
-
intent:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
presetName: "ltx_image_to_video",
|
|
68
|
+
intent:
|
|
69
|
+
"Generate high-quality cinematic video with audio from a static image using LTX Video 2.0 Pro.",
|
|
70
|
+
modelId: "fal-ai/ltx-2/image-to-video",
|
|
71
|
+
inputType: "image",
|
|
72
|
+
outputType: "video",
|
|
73
|
+
promptEnhancer: "ltx2",
|
|
74
|
+
input_schema: {
|
|
75
|
+
prompt: {
|
|
76
|
+
type: "string",
|
|
77
|
+
description: "Detailed description of the motion and scene.",
|
|
78
|
+
},
|
|
79
|
+
image_url: {
|
|
80
|
+
type: "string",
|
|
81
|
+
description: "URL of the start frame image.",
|
|
82
|
+
},
|
|
83
|
+
negative_prompt: {
|
|
84
|
+
type: "string",
|
|
85
|
+
description: "Elements to avoid in the video.",
|
|
86
|
+
},
|
|
87
|
+
aspect_ratio: {
|
|
88
|
+
type: "string",
|
|
89
|
+
enum: ["16:9", "9:16", "1:1", "4:3", "3:4"],
|
|
90
|
+
default: "16:9",
|
|
91
|
+
},
|
|
92
|
+
completion_mode: {
|
|
93
|
+
type: "string",
|
|
94
|
+
enum: ["time", "motion"],
|
|
95
|
+
default: "time",
|
|
96
|
+
},
|
|
97
|
+
duration: {
|
|
98
|
+
type: "integer",
|
|
99
|
+
enum: [5, 10],
|
|
100
|
+
default: 5,
|
|
101
|
+
description: "Duration in seconds.",
|
|
102
|
+
},
|
|
103
|
+
seed: {
|
|
104
|
+
type: "integer",
|
|
105
|
+
description: "Random seed for reproducibility.",
|
|
106
|
+
},
|
|
68
107
|
},
|
|
69
|
-
inputType: "text",
|
|
70
|
-
outputType: "image",
|
|
71
108
|
},
|
|
72
109
|
{
|
|
73
|
-
presetName: "
|
|
74
|
-
intent:
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
inputType: "
|
|
110
|
+
presetName: "ltx_retake_video",
|
|
111
|
+
intent:
|
|
112
|
+
"Perform selective video editing and targetted alterations on existing videos using LTX-2.",
|
|
113
|
+
modelId: "fal-ai/ltx-2/retake-video",
|
|
114
|
+
inputType: "video",
|
|
78
115
|
outputType: "video",
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
116
|
+
promptEnhancer: "ltx2",
|
|
117
|
+
input_schema: {
|
|
118
|
+
prompt: {
|
|
119
|
+
type: "string",
|
|
120
|
+
description: "New prompt defining the changes.",
|
|
121
|
+
},
|
|
122
|
+
video_url: { type: "string", description: "URL of the video to edit." },
|
|
123
|
+
start_time: {
|
|
124
|
+
type: "number",
|
|
125
|
+
description: "Start timestamp for the edit.",
|
|
126
|
+
},
|
|
127
|
+
end_time: { type: "number", description: "End timestamp for the edit." },
|
|
128
|
+
},
|
|
87
129
|
},
|
|
88
130
|
];
|
|
89
131
|
|
|
@@ -92,11 +134,27 @@ export const DEFAULT_PRESETS: FalPresetConfig[] = [
|
|
|
92
134
|
* Defaults to DEFAULT_PRESETS if no path is provided or if the file cannot be read.
|
|
93
135
|
*/
|
|
94
136
|
export function loadFalConfig(): FalConfig {
|
|
95
|
-
|
|
137
|
+
let configPath = process.env.FAL_CONFIG_JSON_PATH;
|
|
138
|
+
|
|
139
|
+
// Fallback to default file search if no env var
|
|
140
|
+
if (!configPath) {
|
|
141
|
+
const potentialPaths = [
|
|
142
|
+
"fal-config.json", // in CWD
|
|
143
|
+
path.join(__dirname, "../../fal-config.json"), // from src/tools/fal in source
|
|
144
|
+
path.join(__dirname, "../../../fal-config.json"), // from dist/tools/fal in build
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
for (const p of potentialPaths) {
|
|
148
|
+
if (fs.existsSync(p)) {
|
|
149
|
+
configPath = p;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
96
154
|
|
|
97
155
|
if (!configPath) {
|
|
98
156
|
console.error(
|
|
99
|
-
"FAL_CONFIG_JSON_PATH not set. Using internal default presets."
|
|
157
|
+
"FAL_CONFIG_JSON_PATH not set and no fal-config.json found. Using internal default presets."
|
|
100
158
|
);
|
|
101
159
|
return { presets: DEFAULT_PRESETS };
|
|
102
160
|
}
|
|
@@ -126,3 +184,42 @@ export function loadFalConfig(): FalConfig {
|
|
|
126
184
|
return { presets: DEFAULT_PRESETS };
|
|
127
185
|
}
|
|
128
186
|
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Save FAL configuration to the JSON file.
|
|
190
|
+
* Only saves if a config file path is available.
|
|
191
|
+
*/
|
|
192
|
+
export function saveFalConfig(config: FalConfig): boolean {
|
|
193
|
+
let configPath = process.env.FAL_CONFIG_JSON_PATH;
|
|
194
|
+
|
|
195
|
+
if (!configPath) {
|
|
196
|
+
const potentialPaths = [
|
|
197
|
+
"fal-config.json",
|
|
198
|
+
path.join(__dirname, "../../fal-config.json"),
|
|
199
|
+
path.join(__dirname, "../../../fal-config.json"),
|
|
200
|
+
];
|
|
201
|
+
for (const p of potentialPaths) {
|
|
202
|
+
if (fs.existsSync(p)) {
|
|
203
|
+
configPath = p;
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!configPath) {
|
|
210
|
+
console.error("Cannot save config: no config file path found.");
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
try {
|
|
215
|
+
const absolutePath = path.isAbsolute(configPath)
|
|
216
|
+
? configPath
|
|
217
|
+
: path.join(process.cwd(), configPath);
|
|
218
|
+
|
|
219
|
+
fs.writeFileSync(absolutePath, JSON.stringify(config, null, 2), "utf-8");
|
|
220
|
+
return true;
|
|
221
|
+
} catch (error: any) {
|
|
222
|
+
console.error(`Error saving FAL config: ${error.message}`);
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
}
|