@codingmantra/mcp-server 0.2.0 β 0.3.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 +82 -9
- package/build/index.js +732 -45
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -2,29 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
The official **Model Context Protocol (MCP)** server connecting AI assistants (Claude Desktop, Cursor, Cline, and Antigravity) to CodingMantra's generative AI media engines.
|
|
4
4
|
|
|
5
|
-
## What's New in v0.
|
|
5
|
+
## What's New in v0.3.0
|
|
6
|
+
- **Social media workflows:** 15 tools for connected accounts, caption creation, drafts, gallery images, immediate publishing, scheduling, status, cancellation, and analytics. Uses the same CodingMantra API key.
|
|
7
|
+
|
|
8
|
+
- **Current API coverage:** Story Teller, HeyGen Talking Avatar IV, and Jewellery Rate Poster tools.
|
|
9
|
+
- **Video contract alignment:** Required prompt/model/duration/resolution/aspect ratio, character descriptions, seed, guidance, and local reference-image resolution.
|
|
10
|
+
- **Terminal job handling:** Polling stops for completed, failed, or cancelled jobs.
|
|
11
|
+
|
|
6
12
|
- πΌοΈ **Native MCP Image Output**: Generated images (including QR codes, logos, try-on shots, and product photos) return standard MCP `ImageContent` so they render directly in your AI assistant's chat window.
|
|
7
13
|
- π **Local File Path Resolution**: Pass local paths (e.g. `./shoe.png` or `/Users/.../portrait.jpg`) directly in tool argumentsβthe server automatically reads and encodes them as base64 data URIs.
|
|
8
|
-
- β‘ **Expanded Tool Suite (
|
|
14
|
+
- β‘ **Expanded Tool Suite (43 Tools)**: Expanded image generation support including Passport Photos, Baby Milestones, YouTube Thumbnails, Blog Images, Nano Banana, Professional Photography, Sketch-to-Real, Human Builder, Apparel/Product/Jewelry Try-On, Festival Posts, Upscaling, and Discovery.
|
|
15
|
+
- π― **Advanced Model & Resolution Parameters**: Direct support for `model`, `modelId`, `promptId`, custom reference images, and server-side credit synchronization.
|
|
9
16
|
- π‘οΈ **Graceful Error Handling & 120s Timeout**: Informative error diagnostics when API keys are missing or requests time out, with clean stdio protocol execution.
|
|
10
17
|
|
|
11
18
|
---
|
|
12
19
|
|
|
13
20
|
## Features & Tool Suite
|
|
14
21
|
|
|
15
|
-
The server exposes **
|
|
22
|
+
The server exposes **43 specialized generative and utility tools** over standard I/O (`stdio`):
|
|
16
23
|
|
|
17
24
|
### 1. Synchronous Image Generation (Immediate Inline Image Output)
|
|
18
|
-
- **`generate_product_photo`** β Generates studio-grade commercial product photos with custom background scenes, ambient occlusion contact shadows,
|
|
25
|
+
- **`generate_product_photo`** β Generates studio-grade commercial product photos with custom background scenes, ambient occlusion contact shadows, camera optics, resolutions (1K, 2K, 4K), aspect ratios, and dynamic logo/text overlays.
|
|
19
26
|
- **`generate_logo`** β Generates bespoke vector-style or 3D brand logos with customizable typography, colors, industries, and reference images.
|
|
20
27
|
- **`try_on_jewelry`** β Virtual luxury jewelry try-on with model styling, metal & gemstone preservation, Fresnel light dispersion, and anatomical contact shadows.
|
|
21
|
-
- **`try_on_apparel`** β Virtual fashion apparel try-on with natural gravitational folds, realistic fabric tension,
|
|
28
|
+
- **`try_on_apparel`** β Virtual fashion apparel try-on with natural gravitational folds, realistic fabric tension, and ground contact shadows.
|
|
22
29
|
- **`try_on_product`** β Universal commercial product staging and virtual try-on across footwear, accessories, cosmetics, eyewear, and furniture with 3-point studio lighting.
|
|
23
30
|
- **`generate_festival_post`** β High-conversion festival marketing graphics, holiday greetings (Diwali, Eid, Christmas, New Year), and promotional banners with product and logo integration.
|
|
31
|
+
- **`build_human`** β Creates photorealistic AI human models tailored for brand photography, fashion, and marketing with complete demographic, facial, hair, and body customization, plus multi-view character sheets (2Γ2 grid).
|
|
24
32
|
- **`generate_youtube_thumbnail`** β High-CTR YouTube thumbnails with rule-of-thirds composition, emotional human expressions, vibrant contrast separation, and legible bold text overlays.
|
|
25
33
|
- **`generate_passport_photo`** β Converts any portrait into an official, compliant passport or visa identity photo with pixel-level facial identity preservation.
|
|
26
34
|
- **`sketch_to_real`** β Transforms hand-drawn sketches, line drawings, or product drafts into photorealistic commercial images while preserving ground-truth silhouettes.
|
|
27
|
-
- **`
|
|
35
|
+
- **`edit_professional_photo`** β Transforms and grades portraits and personal photos into magazine-grade studio or editorial photography with natural dermal micro-pores and optical depth of field.
|
|
36
|
+
- **`edit_nano_banana`** β Creative multi-reference image editor and compositor combining multiple subjects, backgrounds, and artistic styles (figurines, chibi, anime, retro, 3D renders).
|
|
37
|
+
- **`generate_blog_image`** β Generates high-impact, editorial blog hero images, article thumbnails, and banners with clean composition, visual hierarchy, intentional negative space, and exact text overlays.
|
|
38
|
+
- **`generate_baby_milestone`** β Creates magical baby milestone keepsake portraits with pristine subject preservation, seamless background cutout, and organic milestone text integration.
|
|
39
|
+
- **`upscale_image`** β Restores a reference image with Pro AI at 4K (60 credits), checks output size and proportions, and returns the image synchronously. Fine details can change; review the result.
|
|
40
|
+
|
|
41
|
+
- **`generate_jewellery_rate_poster`** β Branded gold and silver rate posters using caller-supplied rates, business details, and optional product/logo images.
|
|
28
42
|
|
|
29
43
|
### 2. QR Code Tools
|
|
30
44
|
- **`generate_qr_code`** β Full-featured custom QR code generator supporting URLs, plain text, Wi-Fi credentials, vCards, emails, and UPI payment strings with custom styling, colors, and error correction.
|
|
@@ -32,20 +46,76 @@ The server exposes **20 specialized generative and utility tools** over standard
|
|
|
32
46
|
|
|
33
47
|
### 3. Account & Discovery Utilities
|
|
34
48
|
- **`get_user_credits`** β Checks your current CodingMantra AI wallet credit balance in real time.
|
|
35
|
-
- **`list_image_models`** β Queries all available CodingMantra AI image generation models (Gemini Flash, Pro,
|
|
49
|
+
- **`list_image_models`** β Queries all available CodingMantra AI image generation models (Gemini Flash, Pro, Grok Imagine 2.0, GPT Image 2.5 Flare), supported resolutions, aspect ratios, and credit costs.
|
|
36
50
|
|
|
37
51
|
### 4. Asynchronous Video Tools (with Job Polling)
|
|
38
|
-
- **`generate_product_video`** β Commercial product videography (Google Veo 3.1 & OpenRouter Wan
|
|
52
|
+
- **`generate_product_video`** β Commercial product videography (Google Veo 3.1 & OpenRouter Wan 3.0).
|
|
39
53
|
- **`generate_apparel_video`** β Model runway and apparel try-on video showcase.
|
|
40
54
|
- **`generate_festival_video`** β Festive event greetings and celebratory motion graphics.
|
|
41
55
|
- **`generate_jewelry_video`** β High-end luxury jewelry videography with realistic optical brilliance dispersion.
|
|
42
56
|
- **`generate_logo_video`** β 3D logo reveal and motion graphic intros.
|
|
43
|
-
- **`
|
|
57
|
+
- **`generate_story_video`** β Cinematic stories with character descriptions, sound effects, and visual atmosphere.
|
|
58
|
+
- **`generate_talking_avatar`** β HeyGen Avatar IV portrait animation with a script, HeyGen voice ID, and performance controls.
|
|
59
|
+
- **`check_video_job_status`** β Real-time polling tool to track background video rendering status (`pending` β `processing` β `completed` / `failed` / `cancelled`).
|
|
44
60
|
|
|
45
61
|
All generations automatically deduct credits from your CodingMantra wallet and persist outputs directly to your online media gallery at [https://codingmantra.com/my-gallery](https://codingmantra.com/my-gallery).
|
|
46
62
|
|
|
47
63
|
---
|
|
48
64
|
|
|
65
|
+
### 5. Social Content & Scheduling
|
|
66
|
+
|
|
67
|
+
- **`get_social_workflow`** β Capabilities, workflow, content guidance, and platform limits.
|
|
68
|
+
- **`list_social_accounts`** β Connected Facebook Pages and Instagram accounts; no provider tokens.
|
|
69
|
+
- **`generate_social_caption`** β Generate or refine a caption and hashtags using images, brandBrief, and saved brand context. Uses credits.
|
|
70
|
+
- **`list_social_drafts`** β Paginated saved drafts (20 per page).
|
|
71
|
+
- **`save_social_draft`** β Create or fully replace a draft; uploads local images. Does not schedule or publish.
|
|
72
|
+
- **`delete_social_draft`** β Remove a saved draft.
|
|
73
|
+
- **`list_social_media`** β Paginate your generated image gallery.
|
|
74
|
+
- **`schedule_social_post`** β Queue final content for automatic future delivery to selected accounts.
|
|
75
|
+
- **`list_social_posts`** β Filter the posting calendar by status, platform, and date range.
|
|
76
|
+
- **`get_social_post`** β Inspect status, errors, retries, and published job IDs.
|
|
77
|
+
- **`update_social_post`** β Edit or reschedule a queued post; retry a failed post with a new future time.
|
|
78
|
+
- **`cancel_social_post`** β Stop a queued post before publication starts.
|
|
79
|
+
- **`delete_social_post`** β Delete an eligible schedule record; does not delete a live platform post.
|
|
80
|
+
- **`publish_social_post`** β Post immediately to one connected account.
|
|
81
|
+
- **`get_social_analytics`** β Recorded reach, engagement, totals, top posts, and posting activity.
|
|
82
|
+
|
|
83
|
+
#### Working with Claude, Codex, Antigravity, and other assistants
|
|
84
|
+
|
|
85
|
+
Connect accounts once in the [Social Media Hub](https://codingmantra.com/tools/digital-marketing/social-media-hub). The same `CODINGMANTRA_API_KEY` used for media generation identifies the owner of all drafts and schedules; browser cookies and Meta access tokens are not needed in your assistant. Account connection/reconnection remains in the browser. Any assistant supporting standard MCP stdio can discover the tools and their schemas. Responses include text plus structured JSON, UTC ISO timestamps, IDs, and pagination fields.
|
|
86
|
+
|
|
87
|
+
Try: βCreate three Facebook posts for my bakeryβs launch. Use a warm voice and these verified opening hours. Save drafts for review, then schedule the approved posts at 9 AM Asia/Kolkata next week.β Or: βShow failed posts, explain their errors, and move this queued post to tomorrow at 6 PM Asia/Kolkata.β
|
|
88
|
+
|
|
89
|
+
Start with `get_social_workflow` and `list_social_accounts`. Use exact returned account IDs. Supply `brandBrief` to isolate a particular brand; otherwise caption generation uses saved brand context. Provide audience, verified facts, tone, offer, and CTA. Combine caption generation with existing image tools, or write captions directly in your assistant without AI credit charges.
|
|
90
|
+
|
|
91
|
+
Instagram supports **exactly one image**, with at most **2,200 characters including hashtags**. Facebook supports text and up to 10 images, with 63,206 characters including hashtags. Video/reel publishing and other networks are not implemented. Generated images may use local file paths; the server resolves them and the backend persists them when drafts or schedules are saved.
|
|
92
|
+
|
|
93
|
+
Scheduling requires `platforms`, `content.caption` (may be empty if there is an image), and a future `scheduledFor` ISO timestamp with an explicit UTC offset. Do not guess an ambiguous timezone. Use `draftId` when queuing a saved draft: the backend atomically consumes it and repeated requests return the same schedule. Immediate publishing has no idempotency guarantee; inspect publication state before retrying a timeout. Successful schedules publish on the backend cron worker even when the assistant is offline.
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"draftId": "returned_draft_id",
|
|
98
|
+
"platforms": [{ "platform": "facebook", "accountId": "returned_page_id", "accountName": "My Bakery" }],
|
|
99
|
+
"content": {
|
|
100
|
+
"caption": "Our opening day is almost here. Join us for fresh bread!",
|
|
101
|
+
"hashtags": ["bakery", "freshbread"],
|
|
102
|
+
"mediaUrls": ["https://example.com/my-generated-image.png"]
|
|
103
|
+
},
|
|
104
|
+
"scheduledFor": "2026-10-10T09:00:00+05:30"
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Deployment order: deploy the updated web API, verify the cron worker, then release/use MCP v0.3.0. The backend must support bearer API keys; older browser-session-only endpoints return 401. For REST examples and the route map, see the repositoryβs `docs/social-mcp-api.md`.
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
## Video parameters
|
|
112
|
+
|
|
113
|
+
General video tools require `prompt` (10β5000 characters), `model`, `timeDuration`, `resolution`, and `aspectRatio`. Use model-supported settings; Veo requires 8 seconds for 1080p, references, or an end frame. Choose one image mode: main image, frames, or references. Reference images accept URLs, data URIs, or local paths (up to 3 for Veo). Optional settings include characters, seed, guidanceScale, soundEffects, and styleAmbiance.
|
|
114
|
+
|
|
115
|
+
Talking Avatar requires `image` (local PNG/JPEG/WebP path or data URI, not a public URL), `script`, and a HeyGen `voiceId`. Optional controls include targetDuration (5β120 seconds, default 15), speed (0.5β1.5), performancePreset, expressiveness, motionPrompt, backgroundMode/backgroundColor, captions, title, resolution (720p or 1080p, default 1080p), and aspectRatio (9:16, 1:1, or 16:9, default 9:16). Scripts must fit the duration budget; credits are calculated by the backend. Poll every 15β30 seconds until completed, failed, or cancelled.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
49
119
|
## Quick Setup
|
|
50
120
|
|
|
51
121
|
### 1. Obtain Your API Key
|
|
@@ -152,6 +222,9 @@ Once configured, restart your AI assistant and try prompts like:
|
|
|
152
222
|
# Build TypeScript
|
|
153
223
|
npm run build
|
|
154
224
|
|
|
225
|
+
# Verify stdio contracts with a mock API (no credits spent)
|
|
226
|
+
npm test
|
|
227
|
+
|
|
155
228
|
# Start server directly on stdio
|
|
156
229
|
CODINGMANTRA_API_KEY=your_key node build/index.js
|
|
157
230
|
```
|
package/build/index.js
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema, ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import { AjvJsonSchemaValidator } from "@modelcontextprotocol/sdk/validation/ajv";
|
|
5
6
|
import { apiClient } from './api-client.js';
|
|
6
7
|
import { formatImageToolResult, resolveImageInput, resolveImagesArray } from './image-utils.js';
|
|
7
8
|
const server = new Server({
|
|
8
9
|
name: "codingmantra-mcp",
|
|
9
|
-
version: "0.
|
|
10
|
+
version: "0.3.0",
|
|
10
11
|
}, {
|
|
12
|
+
instructions: "For social media, start with get_social_workflow and list_social_accounts. Create captions and images, save drafts for review, then schedule or publish according to the userβs request. Use exact connected account IDs and explicit timezone offsets. Only Facebook Pages and Instagram image posts are supported. Keep social provider tokens on the backend.",
|
|
11
13
|
capabilities: {
|
|
12
14
|
tools: {},
|
|
13
15
|
},
|
|
@@ -22,26 +24,38 @@ const IMAGE_SOURCE_SCHEMA = {
|
|
|
22
24
|
}
|
|
23
25
|
};
|
|
24
26
|
const COMMON_VIDEO_PROPERTIES = {
|
|
25
|
-
prompt: { type: "string", description: "
|
|
27
|
+
prompt: { type: "string", minLength: 10, maxLength: 5000, description: "Required video description or creative prompt (10-5000 characters)." },
|
|
26
28
|
mainImage: { type: "string", description: "Base64 data URI, local file path, or public URL for the main subject image (Image-to-Video mode)." },
|
|
27
29
|
startImage: { type: "string", description: "Base64 data URI, local file path, or public URL for the first frame." },
|
|
28
30
|
endImage: { type: "string", description: "Base64 data URI, local file path, or public URL for the last frame." },
|
|
29
31
|
referenceImages: {
|
|
30
32
|
type: "array",
|
|
31
|
-
|
|
32
|
-
description: "
|
|
33
|
+
maxItems: 4,
|
|
34
|
+
items: { type: "object", properties: { image: { type: "string", description: "Public image URL, data URI, or local file path." }, label: { type: "string", description: "Optional reference label." } }, required: ["image"] },
|
|
35
|
+
description: "Reference images for style matching. Choose only one image mode: main image, frames, or references. Veo supports up to 3 references and requires 8 seconds for references or an end frame."
|
|
33
36
|
},
|
|
34
37
|
negativePrompt: { type: "string", description: "Elements to exclude from the video." },
|
|
35
|
-
dialogue: { type: "string", description: "Optional voiceover or dialogue script." },
|
|
38
|
+
dialogue: { type: "string", maxLength: 200, description: "Optional voiceover or dialogue script (up to 200 characters)." },
|
|
36
39
|
soundSuggestion: { type: "string", description: "Background music or sound effects direction." },
|
|
37
40
|
cameraMotion: { type: "string", description: "Camera motion instructions (e.g., 'orbit right', 'slow push-in')." },
|
|
38
41
|
ambientNoise: { type: "string", description: "Ambient sound description." },
|
|
39
42
|
language: { type: "string", description: "Voiceover language." },
|
|
40
|
-
timeDuration: { type: "string", description: "
|
|
41
|
-
resolution: { type: "string", description: "
|
|
42
|
-
model: { type: "string", description: "Model slug (e.g., 'google/veo-3.1-fast', '
|
|
43
|
-
aspectRatio: { type: "string", description: "
|
|
44
|
-
generateAudio: { type: "boolean", description: "Whether to generate synchronized audio. Default is false." }
|
|
43
|
+
timeDuration: { type: "string", description: "Required duration in seconds supported by the selected model. Veo supports 4, 6, or 8; use 8 for 1080p, references, or an end frame." },
|
|
44
|
+
resolution: { type: "string", description: "Required resolution supported by the selected model (480p, 720p, 768p, or 1080p)." },
|
|
45
|
+
model: { type: "string", description: "Model slug (e.g., 'google/veo-3.1-fast', 'alibaba/wan-3.0')." },
|
|
46
|
+
aspectRatio: { type: "string", description: "Required aspect ratio supported by the selected model (e.g., 9:16 or 16:9)." },
|
|
47
|
+
generateAudio: { type: "boolean", description: "Whether to generate synchronized audio. Default is false." },
|
|
48
|
+
seed: { type: "integer", minimum: 0, maximum: Number.MAX_SAFE_INTEGER, description: "Optional nonnegative random seed for models that support it." },
|
|
49
|
+
guidanceScale: { type: "number", description: "Optional guidance strength for models that support it." },
|
|
50
|
+
soundEffects: { type: "string", description: "Sound effects direction for Story Teller." },
|
|
51
|
+
styleAmbiance: { type: "string", description: "Visual style and atmosphere for Story Teller." },
|
|
52
|
+
characters: { type: "array", description: "Optional named characters for consistent storytelling.", items: {
|
|
53
|
+
type: "object", properties: {
|
|
54
|
+
id: { type: "string", description: "Unique character ID." },
|
|
55
|
+
name: { type: "string", description: "Character name." },
|
|
56
|
+
description: { type: "string", description: "Character appearance and role." }
|
|
57
|
+
}, required: ["id", "name", "description"]
|
|
58
|
+
} }
|
|
45
59
|
};
|
|
46
60
|
// βββ Tool Definitions ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
47
61
|
// 1. Product Photography
|
|
@@ -107,7 +121,7 @@ const GENERATE_PRODUCT_PHOTO_TOOL = {
|
|
|
107
121
|
// 2. Logo Creator
|
|
108
122
|
const GENERATE_LOGO_TOOL = {
|
|
109
123
|
name: "generate_logo",
|
|
110
|
-
description: "Generates bespoke vector-style
|
|
124
|
+
description: "Generates bespoke vector-style brand logos, monograms, emblems, and modern wordmarks with character-perfect typography, color palettes, and reference image guidance. Default model is Flash. Returns the generated logo directly for inline display (synchronous).",
|
|
111
125
|
inputSchema: {
|
|
112
126
|
type: "object",
|
|
113
127
|
properties: {
|
|
@@ -137,15 +151,19 @@ const GENERATE_LOGO_TOOL = {
|
|
|
137
151
|
},
|
|
138
152
|
aspectRatio: {
|
|
139
153
|
type: "string",
|
|
140
|
-
description: "Output aspect ratio. Default is '1:1'.",
|
|
154
|
+
description: "Output aspect ratio ('1:1', '16:9', '4:3'). Default is '1:1'.",
|
|
155
|
+
},
|
|
156
|
+
model: {
|
|
157
|
+
type: "string",
|
|
158
|
+
description: "Model tier to use ('flash' or 'pro'). Default is 'flash' (google/gemini-3.1-flash-image)."
|
|
141
159
|
},
|
|
142
160
|
modelId: {
|
|
143
161
|
type: "string",
|
|
144
|
-
description: "
|
|
162
|
+
description: "Full image model ID if specific model desired (e.g. google/gemini-3.1-flash-image).",
|
|
145
163
|
},
|
|
146
164
|
resolution: {
|
|
147
165
|
type: "string",
|
|
148
|
-
description: "Output resolution ('1K', '2K'). Default is '1K'.",
|
|
166
|
+
description: "Output resolution ('1K', '2K', '4K'). Default is '1K'.",
|
|
149
167
|
},
|
|
150
168
|
referenceImage: {
|
|
151
169
|
type: "string",
|
|
@@ -189,7 +207,7 @@ const TRY_ON_JEWELRY_TOOL = {
|
|
|
189
207
|
},
|
|
190
208
|
model: {
|
|
191
209
|
type: "string",
|
|
192
|
-
description: "Model tier slug ('standard', 'pro', 'flash'). Default is '
|
|
210
|
+
description: "Model tier slug ('standard', 'pro', 'flash'). Default is 'flash'."
|
|
193
211
|
},
|
|
194
212
|
referenceImage: {
|
|
195
213
|
type: "string",
|
|
@@ -218,7 +236,7 @@ const TRY_ON_JEWELRY_TOOL = {
|
|
|
218
236
|
// 4. Apparel Try-On
|
|
219
237
|
const TRY_ON_APPAREL_TOOL = {
|
|
220
238
|
name: "try_on_apparel",
|
|
221
|
-
description: "Virtual fashion apparel try-on. Drapes garments realistically along model anatomy with natural gravitational folds, realistic tension,
|
|
239
|
+
description: "Virtual fashion apparel try-on. Drapes garments realistically along model anatomy with natural gravitational folds, realistic tension, ambient occlusion contact shadows, and editorial lighting. Default model tier is Flash. Returns generated image directly (synchronous).",
|
|
222
240
|
inputSchema: {
|
|
223
241
|
type: "object",
|
|
224
242
|
properties: {
|
|
@@ -237,12 +255,16 @@ const TRY_ON_APPAREL_TOOL = {
|
|
|
237
255
|
},
|
|
238
256
|
aspectRatio: {
|
|
239
257
|
type: "string",
|
|
240
|
-
description: "Output aspect ratio ('
|
|
258
|
+
description: "Output aspect ratio ('9:16', '1:1', '16:9', '4:5'). Default is '9:16'."
|
|
241
259
|
},
|
|
242
260
|
resolution: {
|
|
243
261
|
type: "string",
|
|
244
262
|
description: "Output resolution ('1K', '2K', '4K'). Default is '1K'."
|
|
245
263
|
},
|
|
264
|
+
model: {
|
|
265
|
+
type: "string",
|
|
266
|
+
description: "The model tier ('flash', 'pro', 'standard'). Default is 'flash'."
|
|
267
|
+
},
|
|
246
268
|
referenceImage: {
|
|
247
269
|
type: "string",
|
|
248
270
|
description: "Optional style reference image URL, data URI, or local path."
|
|
@@ -266,7 +288,7 @@ const TRY_ON_APPAREL_TOOL = {
|
|
|
266
288
|
// 5. Product Try-On
|
|
267
289
|
const TRY_ON_PRODUCT_TOOL = {
|
|
268
290
|
name: "try_on_product",
|
|
269
|
-
description: "Universal commercial product staging and try-on across footwear, accessories, watches, eyewear, cosmetics, and furniture with 3-point studio lighting and ambient occlusion contact shadows. Returns generated image directly (synchronous).",
|
|
291
|
+
description: "Universal commercial product staging and try-on across footwear, accessories, watches, eyewear, cosmetics, and furniture with 3-point studio lighting and ambient occlusion contact shadows. Default model tier is Flash. Returns generated image directly (synchronous).",
|
|
270
292
|
inputSchema: {
|
|
271
293
|
type: "object",
|
|
272
294
|
properties: {
|
|
@@ -295,6 +317,10 @@ const TRY_ON_PRODUCT_TOOL = {
|
|
|
295
317
|
type: "string",
|
|
296
318
|
description: "Output resolution ('1K', '2K', '4K'). Default is '1K'."
|
|
297
319
|
},
|
|
320
|
+
model: {
|
|
321
|
+
type: "string",
|
|
322
|
+
description: "The model tier ('flash', 'pro', 'standard'). Default is 'flash'."
|
|
323
|
+
},
|
|
298
324
|
referenceImage: {
|
|
299
325
|
type: "string",
|
|
300
326
|
description: "Optional style reference image."
|
|
@@ -314,7 +340,7 @@ const TRY_ON_PRODUCT_TOOL = {
|
|
|
314
340
|
// 6. Festival Post Generator
|
|
315
341
|
const GENERATE_FESTIVAL_POST_TOOL = {
|
|
316
342
|
name: "generate_festival_post",
|
|
317
|
-
description: "Generates high-conversion festival marketing graphics, holiday greetings (Diwali, Eid, Christmas, New Year, Valentine's), and promotional event banners with product and brand logo integration. Returns generated image directly (synchronous).",
|
|
343
|
+
description: "Generates high-conversion festival marketing graphics, holiday greetings (Diwali, Eid, Christmas, New Year, Valentine's), and promotional event banners with product and brand logo integration. Default model is Flash. Returns generated image directly (synchronous).",
|
|
318
344
|
inputSchema: {
|
|
319
345
|
type: "object",
|
|
320
346
|
properties: {
|
|
@@ -338,6 +364,10 @@ const GENERATE_FESTIVAL_POST_TOOL = {
|
|
|
338
364
|
type: "string",
|
|
339
365
|
description: "Supporting promotional message or contact details."
|
|
340
366
|
},
|
|
367
|
+
model: {
|
|
368
|
+
type: "string",
|
|
369
|
+
description: "The model tier ('flash', 'pro', 'standard'). Default is 'flash' (Gemini 3.1 Flash)."
|
|
370
|
+
},
|
|
341
371
|
aspectRatio: {
|
|
342
372
|
type: "string",
|
|
343
373
|
description: "Output aspect ratio ('1:1', '9:16', '16:9'). Default is '1:1'."
|
|
@@ -350,7 +380,47 @@ const GENERATE_FESTIVAL_POST_TOOL = {
|
|
|
350
380
|
required: ["festivalPrompt"]
|
|
351
381
|
}
|
|
352
382
|
};
|
|
353
|
-
// 7.
|
|
383
|
+
// 7. Human Builder / Virtual Model Generator
|
|
384
|
+
const BUILD_HUMAN_TOOL = {
|
|
385
|
+
name: "build_human",
|
|
386
|
+
description: "Creates photorealistic AI human models tailored for brand photography, fashion, ecommerce, and marketing campaigns with complete demographic, facial, hair, and body customization, plus multi-view character sheets (2x2 grid). Default model tier is Flash. Returns generated image directly (synchronous).",
|
|
387
|
+
inputSchema: {
|
|
388
|
+
type: "object",
|
|
389
|
+
properties: {
|
|
390
|
+
name: { type: "string", description: "Optional name or character identifier for the model." },
|
|
391
|
+
age: { type: "string", description: "Age category or specific age (e.g., 'Young Adult', '25 years old', 'Middle-aged')." },
|
|
392
|
+
gender: { type: "string", description: "Gender identity (e.g., 'Female', 'Male', 'Non-binary')." },
|
|
393
|
+
culturalTraits: { type: "string", description: "Ethnicity or cultural heritage (e.g., 'South Asian', 'East Asian', 'Caucasian', 'African')." },
|
|
394
|
+
country: { type: "string", description: "Country of origin (e.g., 'India', 'Japan', 'France', 'Brazil')." },
|
|
395
|
+
skinTone: { type: "string", description: "Complexion and skin tone (e.g., 'Medium Warm', 'Fair Porcelain', 'Rich Deep Bronze')." },
|
|
396
|
+
eyeColor: { type: "string", description: "Eye color (e.g., 'Dark Brown', 'Hazel Green', 'Deep Blue')." },
|
|
397
|
+
eyeShape: { type: "string", description: "Eye shape (e.g., 'Almond', 'Round', 'Monolid', 'Hooded')." },
|
|
398
|
+
noseShape: { type: "string", description: "Nose shape (e.g., 'Natural Straight', 'Aquiline', 'Button', 'Broad')." },
|
|
399
|
+
faceShape: { type: "string", description: "Face shape (e.g., 'Oval', 'Square', 'Heart', 'Round')." },
|
|
400
|
+
hairStyle: { type: "string", description: "Hairstyle (e.g., 'Long Waves', 'Buzz Cut', 'Sleek Bob', 'Afro', 'Layered Cut')." },
|
|
401
|
+
hairColor: { type: "string", description: "Hair color (e.g., 'Natural Black', 'Chestnut Brown', 'Honey Blonde')." },
|
|
402
|
+
hairThickness: { type: "string", description: "Hair density (e.g., 'Thick', 'Medium', 'Fine')." },
|
|
403
|
+
hairType: { type: "string", description: "Hair texture (e.g., 'Straight', 'Wavy', 'Curly', 'Coily')." },
|
|
404
|
+
bodySize: { type: "string", description: "Body build (e.g., 'Petite', 'Slim Athletic', 'Medium', 'Curvy', 'Plus Size')." },
|
|
405
|
+
bodyHeight: { type: "string", description: "Height description (e.g., 'Petite', 'Average', 'Tall Fashion Model')." },
|
|
406
|
+
bodyShape: { type: "string", description: "Body shape (e.g., 'Hourglass', 'Athletic Rectangular', 'Pear', 'Inverted Triangle')." },
|
|
407
|
+
muscleDefinition: { type: "string", description: "Muscle definition (e.g., 'Soft Natural', 'Toned Athletic', 'Defined Muscular')." },
|
|
408
|
+
cupSize: { type: "string", description: "Bust proportion if female (e.g., 'Small', 'Medium', 'Full')." },
|
|
409
|
+
extraDescription: { type: "string", description: "Extra unique physical traits (e.g., 'light freckles across nose bridge, subtle smile')." },
|
|
410
|
+
customTweakPrompt: { type: "string", description: "Custom refinement or scene styling prompt (e.g., 'wearing an ivory cashmere turtleneck against a warm minimalist studio backdrop')." },
|
|
411
|
+
generateMultiView: { type: "boolean", description: "Generate a 4-panel consistent character sheet in a 2x2 grid (Front, Side, 3/4, Close-up detail). Default is false." },
|
|
412
|
+
referenceImages: {
|
|
413
|
+
type: "array",
|
|
414
|
+
items: { type: "string" },
|
|
415
|
+
description: "Optional array of reference face or body images (URLs, data URIs, or local file paths) to guide identity."
|
|
416
|
+
},
|
|
417
|
+
aspectRatio: { type: "string", description: "Output aspect ratio ('1:1', '9:16', '4:5', '16:9'). Default is '1:1'." },
|
|
418
|
+
resolution: { type: "string", description: "Output resolution ('1K', '2K', '4K'). Default is '1K'." },
|
|
419
|
+
model: { type: "string", description: "Model tier ('flash', 'pro', 'standard'). Default is 'flash'." }
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
// 8. YouTube Thumbnail Generator
|
|
354
424
|
const GENERATE_YOUTUBE_THUMBNAIL_TOOL = {
|
|
355
425
|
name: "generate_youtube_thumbnail",
|
|
356
426
|
description: "Generates high-CTR YouTube thumbnails with rule-of-thirds composition, emotional human expressions, vibrant contrast separation, and legible bold text overlays. Returns generated image directly (synchronous).",
|
|
@@ -377,13 +447,29 @@ const GENERATE_YOUTUBE_THUMBNAIL_TOOL = {
|
|
|
377
447
|
type: "string",
|
|
378
448
|
description: "Optional channel/brand logo to place in corner."
|
|
379
449
|
},
|
|
450
|
+
referenceImage: {
|
|
451
|
+
type: "string",
|
|
452
|
+
description: "Optional style or concept reference image (URL, data URI, or local file path)."
|
|
453
|
+
},
|
|
454
|
+
promptId: {
|
|
455
|
+
type: "string",
|
|
456
|
+
description: "Optional ID or title of a pre-defined layout style template from youtubeThumbnailPrompts."
|
|
457
|
+
},
|
|
458
|
+
model: {
|
|
459
|
+
type: "string",
|
|
460
|
+
description: "Model tier ('flash', 'pro', 'standard'). Default is 'flash' (google/gemini-3.1-flash-image)."
|
|
461
|
+
},
|
|
462
|
+
modelId: {
|
|
463
|
+
type: "string",
|
|
464
|
+
description: "The image model ID."
|
|
465
|
+
},
|
|
380
466
|
aspectRatio: {
|
|
381
467
|
type: "string",
|
|
382
468
|
description: "Thumbnail aspect ratio. Default is '16:9'."
|
|
383
469
|
},
|
|
384
470
|
resolution: {
|
|
385
471
|
type: "string",
|
|
386
|
-
description: "Output resolution ('1K', '2K'). Default is '1K'."
|
|
472
|
+
description: "Output resolution ('1K', '2K', '4K'). Default is '1K'."
|
|
387
473
|
}
|
|
388
474
|
},
|
|
389
475
|
required: ["prompt"]
|
|
@@ -392,34 +478,50 @@ const GENERATE_YOUTUBE_THUMBNAIL_TOOL = {
|
|
|
392
478
|
// 8. Passport Photo Creator
|
|
393
479
|
const GENERATE_PASSPORT_PHOTO_TOOL = {
|
|
394
480
|
name: "generate_passport_photo",
|
|
395
|
-
description: "Converts any portrait into an official, compliant passport or visa identity photo with pixel-level facial identity preservation, neutral lighting, and plain white/off-white background. Returns generated image directly (synchronous).",
|
|
481
|
+
description: "Converts any portrait into an official, compliant passport or visa identity photo with pixel-level facial identity preservation, neutral lighting, and plain white/off-white background. Default model tier is Flash. Default aspect ratio is '1:1'. Returns generated image directly (synchronous).",
|
|
396
482
|
inputSchema: {
|
|
397
483
|
type: "object",
|
|
398
484
|
properties: {
|
|
399
485
|
photoDataUri: {
|
|
400
486
|
type: "string",
|
|
401
|
-
description: "Source portrait photo (URL, data URI, or local file path)."
|
|
487
|
+
description: "Source portrait photo (URL, data URI, or local file path) to convert."
|
|
402
488
|
},
|
|
403
489
|
prompt: {
|
|
404
490
|
type: "string",
|
|
405
491
|
description: "Adjustments (e.g., 'white background, formal dark navy business suit, centered frontal view')."
|
|
406
492
|
},
|
|
493
|
+
promptId: {
|
|
494
|
+
type: "string",
|
|
495
|
+
description: "Optional ID or title of a pre-defined style template from passportPhotoPrompts."
|
|
496
|
+
},
|
|
497
|
+
referenceImage: {
|
|
498
|
+
type: "string",
|
|
499
|
+
description: "Optional style reference image (URL, data URI, or local file path) to guide attire or lighting."
|
|
500
|
+
},
|
|
501
|
+
model: {
|
|
502
|
+
type: "string",
|
|
503
|
+
description: "Model tier ('flash', 'pro', 'standard'). Default is 'flash' (google/gemini-3.1-flash-image)."
|
|
504
|
+
},
|
|
505
|
+
modelId: {
|
|
506
|
+
type: "string",
|
|
507
|
+
description: "The image model ID."
|
|
508
|
+
},
|
|
407
509
|
aspectRatio: {
|
|
408
510
|
type: "string",
|
|
409
|
-
description: "Passport aspect ratio ('1:1', '4:5'). Default is '1:1'."
|
|
511
|
+
description: "Passport aspect ratio ('1:1', '4:5', '3:4'). Default is '1:1'."
|
|
410
512
|
},
|
|
411
513
|
resolution: {
|
|
412
514
|
type: "string",
|
|
413
|
-
description: "Output resolution ('1K', '2K'). Default is '1K'."
|
|
515
|
+
description: "Output resolution ('1K', '2K', '4K'). Default is '1K'."
|
|
414
516
|
}
|
|
415
517
|
},
|
|
416
518
|
required: ["photoDataUri"]
|
|
417
519
|
}
|
|
418
520
|
};
|
|
419
|
-
//
|
|
521
|
+
// 10. Sketch to Real
|
|
420
522
|
const SKETCH_TO_REAL_TOOL = {
|
|
421
523
|
name: "sketch_to_real",
|
|
422
|
-
description: "Transforms hand-drawn sketches, line drawings, or product drafts into photorealistic commercial images while strictly preserving the sketched silhouette, proportions, and outlines. Returns generated image directly (synchronous).",
|
|
524
|
+
description: "Transforms hand-drawn sketches, line drawings, or product drafts into photorealistic commercial images while strictly preserving the sketched silhouette, proportions, and outlines. Default model tier is Flash. Returns generated image directly (synchronous).",
|
|
423
525
|
inputSchema: {
|
|
424
526
|
type: "object",
|
|
425
527
|
properties: {
|
|
@@ -435,9 +537,29 @@ const SKETCH_TO_REAL_TOOL = {
|
|
|
435
537
|
type: "string",
|
|
436
538
|
description: "Target render style ('Photorealistic', 'Cinematic', '3D Render'). Default is 'Photorealistic'."
|
|
437
539
|
},
|
|
540
|
+
model: {
|
|
541
|
+
type: "string",
|
|
542
|
+
description: "Model tier ('flash', 'pro', 'standard'). Default is 'flash'."
|
|
543
|
+
},
|
|
544
|
+
referenceImage: {
|
|
545
|
+
type: "string",
|
|
546
|
+
description: "Optional style/concept reference image (URL, data URI, or local file path)."
|
|
547
|
+
},
|
|
548
|
+
logoImage: {
|
|
549
|
+
type: "string",
|
|
550
|
+
description: "Optional brand logo overlay (URL, data URI, or local file path)."
|
|
551
|
+
},
|
|
552
|
+
overlayText: {
|
|
553
|
+
type: "string",
|
|
554
|
+
description: "Optional headline text overlay."
|
|
555
|
+
},
|
|
556
|
+
marketingText: {
|
|
557
|
+
type: "string",
|
|
558
|
+
description: "Optional marketing copy overlay."
|
|
559
|
+
},
|
|
438
560
|
aspectRatio: {
|
|
439
561
|
type: "string",
|
|
440
|
-
description: "Output aspect ratio ('1:1', '16:9', '9:16'). Default is '1:1'."
|
|
562
|
+
description: "Output aspect ratio ('1:1', '16:9', '9:16', '4:5'). Default is '1:1'."
|
|
441
563
|
},
|
|
442
564
|
resolution: {
|
|
443
565
|
type: "string",
|
|
@@ -447,10 +569,201 @@ const SKETCH_TO_REAL_TOOL = {
|
|
|
447
569
|
required: ["sketchImage"]
|
|
448
570
|
}
|
|
449
571
|
};
|
|
450
|
-
//
|
|
572
|
+
// 11. Professional Photography Editor
|
|
573
|
+
const EDIT_PROFESSIONAL_PHOTO_TOOL = {
|
|
574
|
+
name: "edit_professional_photo",
|
|
575
|
+
description: "Transforms, grades, and enhances portraits and lifestyle photos into magazine-grade studio or commercial editorial photography. Enforces natural dermal micro-pores, authentic iris catchlights, directional studio lighting, and realistic depth of field. Default model tier is Flash. Returns generated image directly (synchronous).",
|
|
576
|
+
inputSchema: {
|
|
577
|
+
type: "object",
|
|
578
|
+
properties: {
|
|
579
|
+
images: {
|
|
580
|
+
type: "array",
|
|
581
|
+
items: IMAGE_SOURCE_SCHEMA,
|
|
582
|
+
description: "Array of subject reference photos (URL, data URI, or local file path). Each item can have 'url', 'dataUrl', or local 'path'. At least one required."
|
|
583
|
+
},
|
|
584
|
+
prompt: {
|
|
585
|
+
type: "string",
|
|
586
|
+
description: "Enhancement instruction or desired photo transformation (e.g., 'warm dusk cinematic lighting, shallow depth of field, natural skin texture, magazine editorial portrait')."
|
|
587
|
+
},
|
|
588
|
+
image: {
|
|
589
|
+
type: "string",
|
|
590
|
+
description: "Convenience single subject photo (URL, data URI, or local file path) if only providing one image."
|
|
591
|
+
},
|
|
592
|
+
referenceImage: {
|
|
593
|
+
type: "string",
|
|
594
|
+
description: "Optional style or concept reference image (URL, data URI, or local file path)."
|
|
595
|
+
},
|
|
596
|
+
promptId: {
|
|
597
|
+
type: "string",
|
|
598
|
+
description: "Optional ID or title of a pre-defined photography scene template."
|
|
599
|
+
},
|
|
600
|
+
model: {
|
|
601
|
+
type: "string",
|
|
602
|
+
description: "Model tier ('flash', 'pro', 'standard'). Default is 'flash' (google/gemini-3.1-flash-image)."
|
|
603
|
+
},
|
|
604
|
+
modelId: {
|
|
605
|
+
type: "string",
|
|
606
|
+
description: "The image model ID."
|
|
607
|
+
},
|
|
608
|
+
resolution: {
|
|
609
|
+
type: "string",
|
|
610
|
+
description: "Output resolution ('1K', '2K', '4K'). Default is '1K'."
|
|
611
|
+
},
|
|
612
|
+
aspectRatio: {
|
|
613
|
+
type: "string",
|
|
614
|
+
description: "Output aspect ratio ('1:1', '4:5', '9:16', '16:9'). Default is '1:1'."
|
|
615
|
+
}
|
|
616
|
+
},
|
|
617
|
+
required: ["prompt"]
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
// 12. Nano Banana Image Editor (AI)
|
|
621
|
+
const EDIT_NANO_BANANA_TOOL = {
|
|
622
|
+
name: "edit_nano_banana",
|
|
623
|
+
description: "Creative multi-reference AI image editor and compositor. Generates, modifies, or restyles images from multiple reference photos and text instructions with multi-subject composition, perspective alignment, ground contact shadows, and versatile artistic styles (photorealistic, action figurine, chibi/Funko Pop, anime/Ghibli, 3D render). Default model tier is Flash. Returns generated image directly (synchronous).",
|
|
624
|
+
inputSchema: {
|
|
625
|
+
type: "object",
|
|
626
|
+
properties: {
|
|
627
|
+
images: {
|
|
628
|
+
type: "array",
|
|
629
|
+
items: IMAGE_SOURCE_SCHEMA,
|
|
630
|
+
description: "Array of reference images (URL, data URI, or local file path). Each item can have 'url', 'dataUrl', or local 'path'. At least one required."
|
|
631
|
+
},
|
|
632
|
+
prompt: {
|
|
633
|
+
type: "string",
|
|
634
|
+
description: "The creative editing or generation prompt describing desired composition, style, or changes."
|
|
635
|
+
},
|
|
636
|
+
image: {
|
|
637
|
+
type: "string",
|
|
638
|
+
description: "Convenience single reference photo (URL, data URI, or local file path) if only providing one image."
|
|
639
|
+
},
|
|
640
|
+
referenceImage: {
|
|
641
|
+
type: "string",
|
|
642
|
+
description: "Optional style or concept reference image (URL, data URI, or local file path)."
|
|
643
|
+
},
|
|
644
|
+
promptId: {
|
|
645
|
+
type: "string",
|
|
646
|
+
description: "Optional ID or title of a pre-defined style template (e.g., 'action-figure', 'funko-pop', 'studio-ghibli', '16bit-game-character')."
|
|
647
|
+
},
|
|
648
|
+
model: {
|
|
649
|
+
type: "string",
|
|
650
|
+
description: "Model tier ('flash', 'pro', 'standard'). Default is 'flash' (google/gemini-3.1-flash-image)."
|
|
651
|
+
},
|
|
652
|
+
modelId: {
|
|
653
|
+
type: "string",
|
|
654
|
+
description: "The image model ID."
|
|
655
|
+
},
|
|
656
|
+
resolution: {
|
|
657
|
+
type: "string",
|
|
658
|
+
description: "Output resolution ('1K', '2K', '4K'). Default is '1K'."
|
|
659
|
+
},
|
|
660
|
+
aspectRatio: {
|
|
661
|
+
type: "string",
|
|
662
|
+
description: "Output aspect ratio ('1:1', '4:5', '9:16', '16:9'). Default is '1:1'."
|
|
663
|
+
}
|
|
664
|
+
},
|
|
665
|
+
required: ["prompt"]
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
// 13. Blog Image Generator (AI)
|
|
669
|
+
const GENERATE_BLOG_IMAGE_TOOL = {
|
|
670
|
+
name: "generate_blog_image",
|
|
671
|
+
description: "Generates high-impact, editorial blog hero images, article thumbnails, and banners with clean composition, visual hierarchy, intentional negative space, and exact text overlays. Default aspect ratio is 16:9. Default model tier is Flash. Returns generated image directly (synchronous).",
|
|
672
|
+
inputSchema: {
|
|
673
|
+
type: "object",
|
|
674
|
+
properties: {
|
|
675
|
+
prompt: {
|
|
676
|
+
type: "string",
|
|
677
|
+
description: "Description of the desired blog hero image, article concept, or editorial illustration."
|
|
678
|
+
},
|
|
679
|
+
overlayText: {
|
|
680
|
+
type: "string",
|
|
681
|
+
description: "Optional short text, title, or headline to overlay legibly on the image."
|
|
682
|
+
},
|
|
683
|
+
referenceImage: {
|
|
684
|
+
type: "string",
|
|
685
|
+
description: "Optional style or aesthetic reference image (URL, data URI, or local file path)."
|
|
686
|
+
},
|
|
687
|
+
promptId: {
|
|
688
|
+
type: "string",
|
|
689
|
+
description: "Optional ID or title of a pre-defined style template from blogImagePrompts (e.g., 'neon-cyber-circuit', 'balancing-stones')."
|
|
690
|
+
},
|
|
691
|
+
model: {
|
|
692
|
+
type: "string",
|
|
693
|
+
description: "Model tier ('flash', 'pro', 'standard'). Default is 'flash' (google/gemini-3.1-flash-image)."
|
|
694
|
+
},
|
|
695
|
+
modelId: {
|
|
696
|
+
type: "string",
|
|
697
|
+
description: "The image model ID."
|
|
698
|
+
},
|
|
699
|
+
resolution: {
|
|
700
|
+
type: "string",
|
|
701
|
+
description: "Output resolution ('1K', '2K', '4K'). Default is '1K'."
|
|
702
|
+
},
|
|
703
|
+
aspectRatio: {
|
|
704
|
+
type: "string",
|
|
705
|
+
description: "Output aspect ratio ('16:9', '1:1', '4:3', '3:4', '9:16', '4:5'). Default is '16:9'."
|
|
706
|
+
}
|
|
707
|
+
},
|
|
708
|
+
required: ["prompt"]
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
// 14. Baby Milestone Generator
|
|
712
|
+
const GENERATE_BABY_MILESTONE_TOOL = {
|
|
713
|
+
name: "generate_baby_milestone",
|
|
714
|
+
description: "Creates magical baby milestone keepsake portraits by isolating the baby and generating enchanting themed backgrounds with organic milestone text integration, while preserving the baby's exact face, expression, skin tone, clothing, and posture. Default model tier is Flash. Default aspect ratio is '1:1'. Returns generated image directly (synchronous).",
|
|
715
|
+
inputSchema: {
|
|
716
|
+
type: "object",
|
|
717
|
+
properties: {
|
|
718
|
+
photoDataUri: {
|
|
719
|
+
type: "string",
|
|
720
|
+
description: "The baby photo (URL, data URI, or local file path) to isolate and preserve as the main subject."
|
|
721
|
+
},
|
|
722
|
+
milestoneValue: {
|
|
723
|
+
type: "number",
|
|
724
|
+
description: "Milestone number (e.g., 1, 3, 6, 12)."
|
|
725
|
+
},
|
|
726
|
+
milestoneUnit: {
|
|
727
|
+
type: "string",
|
|
728
|
+
enum: ["month", "year"],
|
|
729
|
+
description: "Unit for milestone ('month' or 'year')."
|
|
730
|
+
},
|
|
731
|
+
customPrompt: {
|
|
732
|
+
type: "string",
|
|
733
|
+
description: "Creative theme or environment instructions (e.g., 'Enchanted woodland forest with soft morning sunbeams and wildflowers')."
|
|
734
|
+
},
|
|
735
|
+
promptId: {
|
|
736
|
+
type: "string",
|
|
737
|
+
description: "Optional ID or title of a pre-defined style preset from babyMilestonePrompts."
|
|
738
|
+
},
|
|
739
|
+
referenceImage: {
|
|
740
|
+
type: "string",
|
|
741
|
+
description: "Optional environmental style reference image (URL, data URI, or local file path)."
|
|
742
|
+
},
|
|
743
|
+
model: {
|
|
744
|
+
type: "string",
|
|
745
|
+
description: "Model tier ('flash', 'pro', 'standard'). Default is 'flash' (google/gemini-3.1-flash-image)."
|
|
746
|
+
},
|
|
747
|
+
modelId: {
|
|
748
|
+
type: "string",
|
|
749
|
+
description: "The image model ID."
|
|
750
|
+
},
|
|
751
|
+
resolution: {
|
|
752
|
+
type: "string",
|
|
753
|
+
description: "Output resolution ('1K', '2K', '4K'). Default is '1K'."
|
|
754
|
+
},
|
|
755
|
+
aspectRatio: {
|
|
756
|
+
type: "string",
|
|
757
|
+
description: "Output aspect ratio ('1:1', '4:5', '3:4', '16:9', '9:16'). Default is '1:1'."
|
|
758
|
+
}
|
|
759
|
+
},
|
|
760
|
+
required: ["photoDataUri"]
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
// 13. Upscale Image
|
|
451
764
|
const UPSCALE_IMAGE_TOOL = {
|
|
452
765
|
name: "upscale_image",
|
|
453
|
-
description: "
|
|
766
|
+
description: "Enhances a reference image with the Pro AI model at 4K. Preserves composition through instructions and validates larger dimensions and matching proportions. AI may alter fine details. Uses 60 credits; returns the upscaled image synchronously.",
|
|
454
767
|
inputSchema: {
|
|
455
768
|
type: "object",
|
|
456
769
|
properties: {
|
|
@@ -526,7 +839,7 @@ const GET_USER_CREDITS_TOOL = {
|
|
|
526
839
|
// 14. List Image Models
|
|
527
840
|
const LIST_IMAGE_MODELS_TOOL = {
|
|
528
841
|
name: "list_image_models",
|
|
529
|
-
description: "Lists all available CodingMantra AI image generation models (e.g., Gemini Flash, Gemini Pro,
|
|
842
|
+
description: "Lists all available CodingMantra AI image generation models (e.g., Gemini Flash, Gemini Pro, Grok Imagine 2.0, GPT Image 2.5 Flare), including supported resolutions, aspect ratios, and credit costs.",
|
|
530
843
|
inputSchema: {
|
|
531
844
|
type: "object",
|
|
532
845
|
properties: {}
|
|
@@ -536,36 +849,93 @@ const LIST_IMAGE_MODELS_TOOL = {
|
|
|
536
849
|
const GENERATE_PRODUCT_VIDEO_TOOL = {
|
|
537
850
|
name: "generate_product_video",
|
|
538
851
|
description: "Generates commercial product videography. Asynchronous: returns a jobId. You MUST use check_video_job_status with the jobId to poll for completion.",
|
|
539
|
-
inputSchema: { type: "object", properties: COMMON_VIDEO_PROPERTIES }
|
|
852
|
+
inputSchema: { type: "object", properties: COMMON_VIDEO_PROPERTIES, required: ["prompt", "model", "resolution", "aspectRatio", "timeDuration"] }
|
|
540
853
|
};
|
|
541
854
|
// 16. Apparel Video Generation (Async)
|
|
542
855
|
const GENERATE_APPAREL_VIDEO_TOOL = {
|
|
543
856
|
name: "generate_apparel_video",
|
|
544
857
|
description: "Generates runway fashion and apparel motion showcase videos. Asynchronous: returns a jobId. You MUST use check_video_job_status with the jobId to poll for completion.",
|
|
545
|
-
inputSchema: { type: "object", properties: COMMON_VIDEO_PROPERTIES }
|
|
858
|
+
inputSchema: { type: "object", properties: COMMON_VIDEO_PROPERTIES, required: ["prompt", "model", "resolution", "aspectRatio", "timeDuration"] }
|
|
546
859
|
};
|
|
547
860
|
// 17. Festival Video Generation (Async)
|
|
548
861
|
const GENERATE_FESTIVAL_VIDEO_TOOL = {
|
|
549
862
|
name: "generate_festival_video",
|
|
550
863
|
description: "Generates celebratory festival greetings and motion graphics. Asynchronous: returns a jobId. You MUST use check_video_job_status with the jobId to poll for completion.",
|
|
551
|
-
inputSchema: { type: "object", properties: COMMON_VIDEO_PROPERTIES }
|
|
864
|
+
inputSchema: { type: "object", properties: COMMON_VIDEO_PROPERTIES, required: ["prompt", "model", "resolution", "aspectRatio", "timeDuration"] }
|
|
552
865
|
};
|
|
553
866
|
// 18. Jewelry Video Generation (Async)
|
|
554
867
|
const GENERATE_JEWELRY_VIDEO_TOOL = {
|
|
555
868
|
name: "generate_jewelry_video",
|
|
556
869
|
description: "Generates luxury jewelry videography with optical brilliance and rotating display. Asynchronous: returns a jobId. You MUST use check_video_job_status with the jobId to poll for completion.",
|
|
557
|
-
inputSchema: { type: "object", properties: COMMON_VIDEO_PROPERTIES }
|
|
870
|
+
inputSchema: { type: "object", properties: COMMON_VIDEO_PROPERTIES, required: ["prompt", "model", "resolution", "aspectRatio", "timeDuration"] }
|
|
558
871
|
};
|
|
559
872
|
// 19. Logo Video Generation (Async)
|
|
560
873
|
const GENERATE_LOGO_VIDEO_TOOL = {
|
|
561
874
|
name: "generate_logo_video",
|
|
562
875
|
description: "Generates 3D logo reveal and motion graphic video intros. Asynchronous: returns a jobId. You MUST use check_video_job_status with the jobId to poll for completion.",
|
|
563
|
-
inputSchema: { type: "object", properties: COMMON_VIDEO_PROPERTIES }
|
|
876
|
+
inputSchema: { type: "object", properties: COMMON_VIDEO_PROPERTIES, required: ["prompt", "model", "resolution", "aspectRatio", "timeDuration"] }
|
|
877
|
+
};
|
|
878
|
+
const GENERATE_STORY_VIDEO_TOOL = {
|
|
879
|
+
name: "generate_story_video",
|
|
880
|
+
description: "Generates cinematic story videos with character descriptions, reference images, sound effects, and atmosphere. Asynchronous: returns a jobId; poll check_video_job_status until completed, failed, or cancelled.",
|
|
881
|
+
inputSchema: { type: "object", properties: COMMON_VIDEO_PROPERTIES, required: ["prompt", "model", "resolution", "aspectRatio", "timeDuration"] }
|
|
882
|
+
};
|
|
883
|
+
const GENERATE_TALKING_AVATAR_TOOL = {
|
|
884
|
+
name: "generate_talking_avatar",
|
|
885
|
+
description: "Animates a portrait with HeyGen Avatar IV lip sync from a script and HeyGen voice ID. Asynchronous: returns a jobId; poll check_video_job_status until completed, failed, or cancelled. Credits are calculated by the server from the script budget and resolution.",
|
|
886
|
+
inputSchema: {
|
|
887
|
+
type: "object",
|
|
888
|
+
properties: {
|
|
889
|
+
image: { type: "string", description: "PNG, JPEG, or WebP portrait as a base64 data URI or local file path. Public URLs are not accepted." },
|
|
890
|
+
speechMode: { type: "string", enum: ["text"], default: "text", description: "Speech source; currently only text is supported." },
|
|
891
|
+
script: { type: "string", minLength: 3, maxLength: 2000, description: "Spoken script. Must fit the selected duration budget and speech speed." },
|
|
892
|
+
voiceId: { type: "string", minLength: 1, maxLength: 150, pattern: "^[A-Za-z0-9_-]+$", description: "HeyGen voice ID for the narration." },
|
|
893
|
+
speed: { type: "number", minimum: 0.5, maximum: 1.5, default: 1, description: "Speech speed multiplier." },
|
|
894
|
+
targetDuration: { type: "integer", minimum: 5, maximum: 120, default: 15, description: "Maximum script duration budget in seconds." },
|
|
895
|
+
performancePreset: { type: "string", enum: ["natural", "professional", "energetic", "friendly", "presenter", "storyteller"], default: "professional", description: "Avatar performance style." },
|
|
896
|
+
expressiveness: { type: "string", enum: ["low", "medium", "high"], description: "Optional expression intensity override." },
|
|
897
|
+
motionPrompt: { type: "string", maxLength: 500, description: "Optional motion instructions overriding the preset." },
|
|
898
|
+
backgroundMode: { type: "string", enum: ["original", "color"], default: "original", description: "Preserve the portrait background or use a solid color." },
|
|
899
|
+
backgroundColor: { type: "string", pattern: "^#[0-9a-fA-F]{6}$", default: "#111827", description: "Solid background color when backgroundMode is color." },
|
|
900
|
+
captions: { type: "boolean", default: false, description: "Whether to add captions." },
|
|
901
|
+
title: { type: "string", maxLength: 100, description: "Optional video title." },
|
|
902
|
+
resolution: { type: "string", enum: ["720p", "1080p"], default: "1080p", description: "Output resolution." },
|
|
903
|
+
aspectRatio: { type: "string", enum: ["9:16", "1:1", "16:9"], default: "9:16", description: "Output aspect ratio." }
|
|
904
|
+
},
|
|
905
|
+
required: ["image", "script", "voiceId"]
|
|
906
|
+
}
|
|
907
|
+
};
|
|
908
|
+
const GENERATE_JEWELLERY_RATE_POSTER_TOOL = {
|
|
909
|
+
name: "generate_jewellery_rate_poster",
|
|
910
|
+
description: "Generates a branded gold and silver rate poster. Synchronous: returns the generated image for inline display. Rates are supplied by the caller, not fetched from a market feed.",
|
|
911
|
+
inputSchema: {
|
|
912
|
+
type: "object",
|
|
913
|
+
properties: {
|
|
914
|
+
scenePrompt: { type: "string", description: "Poster scene, background, and visual style." },
|
|
915
|
+
productImage: { type: "string", description: "Optional jewelry image URL, data URI, or local file path." },
|
|
916
|
+
logoImage: { type: "string", description: "Optional brand logo URL, data URI, or local file path." },
|
|
917
|
+
goldRate24k: { type: "string", description: "24K gold rate text, including currency and units." },
|
|
918
|
+
goldRate22k: { type: "string", description: "22K gold rate text, including currency and units." },
|
|
919
|
+
goldRate18k: { type: "string", description: "18K gold rate text, including currency and units." },
|
|
920
|
+
goldRate14k: { type: "string", description: "14K gold rate text, including currency and units." },
|
|
921
|
+
silverRate: { type: "string", description: "Silver rate text, including currency and units." },
|
|
922
|
+
date: { type: "string", description: "Date to display on the poster." },
|
|
923
|
+
brandName: { type: "string", description: "Jewelry business name." },
|
|
924
|
+
tagLine: { type: "string", description: "Optional brand tagline." },
|
|
925
|
+
footerText: { type: "string", description: "Optional footer or disclaimer." },
|
|
926
|
+
address: { type: "string", description: "Business address." },
|
|
927
|
+
phoneNumber: { type: "string", description: "Business contact number." },
|
|
928
|
+
model: { type: "string", description: "Image model slug; use list_image_models to discover models." },
|
|
929
|
+
resolution: { type: "string", description: "Resolution supported by the selected model (1K, 2K, or 4K)." },
|
|
930
|
+
aspectRatio: { type: "string", default: "1:1", description: "Aspect ratio supported by the selected model." }
|
|
931
|
+
},
|
|
932
|
+
required: ["scenePrompt"]
|
|
933
|
+
}
|
|
564
934
|
};
|
|
565
935
|
// 20. Check Video Job Status (Polling)
|
|
566
936
|
const CHECK_JOB_STATUS_TOOL = {
|
|
567
937
|
name: "check_video_job_status",
|
|
568
|
-
description: "Checks the real-time status of an asynchronous video generation job. Call this repeatedly (every 10-30 seconds) until the job status is 'completed' or '
|
|
938
|
+
description: "Checks the real-time status of an asynchronous video generation job. Call this repeatedly (every 10-30 seconds) until the job status is 'completed', 'failed', or 'cancelled'.",
|
|
569
939
|
inputSchema: {
|
|
570
940
|
type: "object",
|
|
571
941
|
properties: {
|
|
@@ -574,19 +944,224 @@ const CHECK_JOB_STATUS_TOOL = {
|
|
|
574
944
|
required: ["jobId"]
|
|
575
945
|
}
|
|
576
946
|
};
|
|
947
|
+
// Social tools share the same API key as media generation; social tokens stay on the server.
|
|
948
|
+
const SOCIAL_ACCOUNT_SCHEMA = {
|
|
949
|
+
type: 'object', properties: {
|
|
950
|
+
platform: { type: 'string', enum: ['facebook', 'instagram'], description: 'Connected social platform.' },
|
|
951
|
+
accountId: { type: 'string', minLength: 1, description: 'Exact account ID returned by list_social_accounts.' },
|
|
952
|
+
accountName: { type: 'string', minLength: 1, description: 'Account display name returned by list_social_accounts.' },
|
|
953
|
+
}, required: ['platform', 'accountId', 'accountName'],
|
|
954
|
+
};
|
|
955
|
+
const SOCIAL_CONTENT_PROPERTIES = {
|
|
956
|
+
caption: { type: 'string', maxLength: 63206, description: 'Post text. Instagram caption plus hashtags must fit 2200 characters.' },
|
|
957
|
+
brandBrief: { type: 'string', maxLength: 4000, description: 'Brand name, audience, voice, offer, facts, and call to action for this post.' },
|
|
958
|
+
hashtags: { type: 'array', maxItems: 30, items: { type: 'string', description: 'Hashtag with or without a leading #.' }, description: 'Relevant hashtags; duplicates already in the caption are omitted during publication.' },
|
|
959
|
+
mediaUrls: { type: 'array', maxItems: 10, items: { type: 'string', description: 'HTTPS image URL, PNG/JPEG/WebP data URI, or local image path.' }, description: 'Images only. Instagram currently requires exactly one image; Facebook accepts up to 10.' },
|
|
960
|
+
};
|
|
961
|
+
const SOCIAL_SCHEDULE_PROPERTIES = {
|
|
962
|
+
draftId: { type: 'string', description: 'Optional saved draft ID. Scheduling consumes it atomically; repeating this request returns the same scheduled post.' },
|
|
963
|
+
socialContentId: { type: 'string', description: 'Optional media library content ID for tracking.' },
|
|
964
|
+
platforms: { type: 'array', minItems: 1, maxItems: 20, items: SOCIAL_ACCOUNT_SCHEMA, description: 'Connected accounts to publish to; select each account once.' },
|
|
965
|
+
content: { type: 'object', properties: SOCIAL_CONTENT_PROPERTIES, required: ['caption'], description: 'Final post caption, hashtags, brand brief, and images.' },
|
|
966
|
+
scheduledFor: { type: 'string', format: 'date-time', description: 'Future ISO 8601 timestamp with explicit UTC offset, e.g. 2026-10-10T09:00:00+05:30. Resolve the userβs timezone before scheduling.' },
|
|
967
|
+
};
|
|
968
|
+
const SOCIAL_ID = { type: 'string', minLength: 1, pattern: '^[A-Za-z0-9_-]+$', description: 'Exact draft or scheduled post ID returned by a social tool.' };
|
|
969
|
+
const socialRead = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true };
|
|
970
|
+
const socialWrite = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true };
|
|
971
|
+
const socialDelete = { ...socialWrite, destructiveHint: true, idempotentHint: true };
|
|
972
|
+
const SOCIAL_TOOLS = [
|
|
973
|
+
{ name: 'get_social_workflow', description: 'Read the social workflow, capabilities, timezone guidance, and platform restrictions before planning content or posting. Read-only; no API call.', annotations: { ...socialRead, openWorldHint: false }, inputSchema: { type: 'object', properties: {} } },
|
|
974
|
+
{ name: 'list_social_accounts', description: 'List connected Facebook Pages and Instagram accounts with IDs, names, permissions, and reconnect status. Read-only; OAuth tokens are never returned. Connect accounts in the web hub first.', annotations: socialRead, inputSchema: { type: 'object', properties: {} } },
|
|
975
|
+
{ name: 'generate_social_caption', description: 'Synchronously create or refine a caption and hashtags from a brief or images. Uses wallet credits and saved brand context unless brandBrief is supplied. Does not publish. Include verified facts, audience, tone, and CTA in the brief; review the result.', annotations: socialWrite, inputSchema: { type: 'object', properties: { ...SOCIAL_CONTENT_PROPERTIES, platform: { type: 'string', enum: ['facebook', 'instagram'], description: 'Target platform; defaults to Instagram.' } } } },
|
|
976
|
+
{ name: 'list_social_drafts', description: 'Read saved drafts, including captions, images, account selections, and proposed dates. Returns 20 per page; use offset for pagination.', annotations: socialRead, inputSchema: { type: 'object', properties: { offset: { type: 'integer', minimum: 0, description: 'Number of drafts to skip.' } } } },
|
|
977
|
+
{ name: 'save_social_draft', description: 'Save a new draft or replace an existing draft by id. Does not queue or publish. Send the complete draft when editing; omitted fields use API defaults. Local images are uploaded and persisted.', annotations: socialWrite, inputSchema: { type: 'object', properties: { ...SOCIAL_CONTENT_PROPERTIES, id: SOCIAL_ID, platforms: { type: 'array', items: SOCIAL_ACCOUNT_SCHEMA, description: 'Optional target accounts; drafts may have no accounts yet.' }, scheduledFor: { type: ['string', 'null'], format: 'date-time', description: 'Optional proposed date with explicit offset; saving does not schedule.' }, socialContentId: { type: 'string', description: 'Optional media library content ID.' } } } },
|
|
978
|
+
{ name: 'delete_social_draft', description: 'Delete one saved draft belonging to the API-key owner. Does not delete a scheduled or published post.', annotations: socialDelete, inputSchema: { type: 'object', properties: { id: SOCIAL_ID }, required: ['id'] } },
|
|
979
|
+
{ name: 'list_social_media', description: 'Read generated images from your gallery for use in posts. Returns public media URLs; use existing image generation tools to create new visuals.', annotations: socialRead, inputSchema: { type: 'object', properties: { page: { type: 'integer', minimum: 1, description: 'Gallery page (default 1).' }, limit: { type: 'integer', minimum: 1, maximum: 50, description: 'Images per page (default 24).' } } } },
|
|
980
|
+
{ name: 'schedule_social_post', description: 'Queue a final post for automatic future publication to connected accounts. Returns a scheduled post ID. ISO timestamps require a UTC offset; the server scheduler publishes even when this assistant is offline. Use draftId to avoid duplicate draft scheduling.', annotations: socialWrite, inputSchema: { type: 'object', properties: SOCIAL_SCHEDULE_PROPERTIES, required: ['platforms', 'content', 'scheduledFor'] } },
|
|
981
|
+
{ name: 'list_social_posts', description: 'Read scheduled, published, failed, or cancelled posts. Filter by platform, status, or date range; use limit/offset for pagination. Dates must include a UTC offset.', annotations: socialRead, inputSchema: { type: 'object', properties: {
|
|
982
|
+
status: { type: 'string', enum: ['scheduled', 'published', 'failed', 'cancelled'], description: 'Post status filter.' },
|
|
983
|
+
platform: { type: 'string', enum: ['facebook', 'instagram'], description: 'Platform filter.' },
|
|
984
|
+
fromDate: { type: 'string', format: 'date-time', description: 'Inclusive start timestamp with offset.' },
|
|
985
|
+
toDate: { type: 'string', format: 'date-time', description: 'Inclusive end timestamp with offset.' },
|
|
986
|
+
limit: { type: 'integer', minimum: 1, maximum: 500, description: 'Page size, default 50.' },
|
|
987
|
+
offset: { type: 'integer', minimum: 0, description: 'Number of posts to skip.' },
|
|
988
|
+
} } },
|
|
989
|
+
{ name: 'get_social_post', description: 'Read one scheduled post, including status, error, retries, and published job IDs. Check this before retrying a failed or ambiguous publication.', annotations: socialRead, inputSchema: { type: 'object', properties: { id: SOCIAL_ID }, required: ['id'] } },
|
|
990
|
+
{ name: 'update_social_post', description: 'Edit a pending schedule, content, or target accounts. Provide a new future scheduledFor to reschedule or retry a failed post. The API rejects changes to posts that are publishing or already published.', annotations: { ...socialWrite, idempotentHint: true }, inputSchema: { type: 'object', properties: { id: SOCIAL_ID, content: { type: 'object', properties: SOCIAL_CONTENT_PROPERTIES, description: 'Fields to change; omitted fields retain their existing values.' }, platforms: SOCIAL_SCHEDULE_PROPERTIES.platforms, scheduledFor: SOCIAL_SCHEDULE_PROPERTIES.scheduledFor }, required: ['id'] } },
|
|
991
|
+
{ name: 'cancel_social_post', description: 'Cancel a queued post so it will not publish. The API rejects cancellation while publishing or after publication. Does not remove an already published platform post.', annotations: socialDelete, inputSchema: { type: 'object', properties: { id: SOCIAL_ID }, required: ['id'] } },
|
|
992
|
+
{ name: 'delete_social_post', description: 'Remove a schedule record. The API prevents deletion during publishing or after publication. Does not delete a live Facebook or Instagram post.', annotations: socialDelete, inputSchema: { type: 'object', properties: { id: SOCIAL_ID }, required: ['id'] } },
|
|
993
|
+
{ name: 'publish_social_post', description: 'Publish immediately to one connected Facebook Page or Instagram account when the user requests posting now. Returns the platform publication result. Images only; Instagram requires exactly one image. Avoid blind retries after timeouts because a post may already be live.', annotations: { ...socialWrite, destructiveHint: true }, inputSchema: { type: 'object', properties: { ...SOCIAL_CONTENT_PROPERTIES, platform: { type: 'string', enum: ['facebook', 'instagram'], description: 'Platform to publish to.' }, accountId: { type: 'string', minLength: 1, description: 'Exact connected account ID from list_social_accounts.' }, socialContentId: { type: 'string', description: 'Optional media library content ID for publication tracking.' }, link: { type: 'string', description: 'Optional HTTPS link for a Facebook post.' } }, required: ['platform', 'accountId', 'caption'] } },
|
|
994
|
+
{ name: 'get_social_analytics', description: 'Read recorded publishing totals, reach, engagement, top posts, and posting activity. Metrics reflect stored provider data and may be incomplete; these are not guaranteed optimal posting times.', annotations: socialRead, inputSchema: { type: 'object', properties: { range: { type: 'string', enum: ['7d', '30d', '90d'], description: 'Reporting range, default 30d.' }, platform: { type: 'string', enum: ['facebook', 'instagram'], description: 'Optional platform filter.' }, accountId: { type: 'string', description: 'Optional connected account filter.' } } } },
|
|
995
|
+
];
|
|
996
|
+
const socialSchemaValidator = new AjvJsonSchemaValidator();
|
|
997
|
+
const socialValidators = new Map(SOCIAL_TOOLS.map(tool => [tool.name, socialSchemaValidator.getValidator(tool.inputSchema)]));
|
|
998
|
+
function normalizeSocialDates(value) {
|
|
999
|
+
if (Array.isArray(value))
|
|
1000
|
+
return value.map(normalizeSocialDates);
|
|
1001
|
+
if (value && typeof value === 'object') {
|
|
1002
|
+
const object = value;
|
|
1003
|
+
const seconds = object._seconds ?? object.seconds;
|
|
1004
|
+
if (typeof seconds === 'number' && Object.keys(object).every(key => ['_seconds', '_nanoseconds', 'seconds', 'nanoseconds'].includes(key))) {
|
|
1005
|
+
return new Date(seconds * 1000).toISOString();
|
|
1006
|
+
}
|
|
1007
|
+
return Object.fromEntries(Object.entries(object).map(([key, nested]) => [key, normalizeSocialDates(nested)]));
|
|
1008
|
+
}
|
|
1009
|
+
return value;
|
|
1010
|
+
}
|
|
1011
|
+
function socialImage(value) {
|
|
1012
|
+
if (typeof value !== 'string')
|
|
1013
|
+
throw new Error('Each media image must be a URL, data URI, or local file path.');
|
|
1014
|
+
const resolved = resolveImageInput(value);
|
|
1015
|
+
if (/^data:image\/(jpeg|png|webp);base64,/i.test(resolved))
|
|
1016
|
+
return resolved;
|
|
1017
|
+
try {
|
|
1018
|
+
if (new URL(resolved).protocol === 'https:')
|
|
1019
|
+
return resolved;
|
|
1020
|
+
}
|
|
1021
|
+
catch { /* invalid source */ }
|
|
1022
|
+
throw new Error('Use an HTTPS image URL or a local PNG, JPEG, or WebP file.');
|
|
1023
|
+
}
|
|
1024
|
+
function socialQuery(args, allowed) {
|
|
1025
|
+
const query = new URLSearchParams();
|
|
1026
|
+
for (const key of allowed)
|
|
1027
|
+
if (args[key] !== undefined)
|
|
1028
|
+
query.set(key, String(args[key]));
|
|
1029
|
+
return query.size ? `?${query}` : '';
|
|
1030
|
+
}
|
|
1031
|
+
function socialId(args) {
|
|
1032
|
+
if (typeof args.id !== 'string' || !/^[A-Za-z0-9_-]+$/.test(args.id))
|
|
1033
|
+
throw new Error('Provide a valid post or draft ID.');
|
|
1034
|
+
return encodeURIComponent(args.id);
|
|
1035
|
+
}
|
|
1036
|
+
async function executeSocialTool(name, rawArgs) {
|
|
1037
|
+
const validated = socialValidators.get(name)(rawArgs);
|
|
1038
|
+
if (!validated.valid)
|
|
1039
|
+
throw new Error(`Invalid ${name} parameters: ${validated.errorMessage}`);
|
|
1040
|
+
const args = { ...rawArgs };
|
|
1041
|
+
if (args.mediaUrls !== undefined) {
|
|
1042
|
+
if (!Array.isArray(args.mediaUrls))
|
|
1043
|
+
throw new Error('mediaUrls must be an array.');
|
|
1044
|
+
args.mediaUrls = args.mediaUrls.map(socialImage);
|
|
1045
|
+
}
|
|
1046
|
+
if (args.content !== undefined) {
|
|
1047
|
+
if (!args.content || typeof args.content !== 'object' || Array.isArray(args.content))
|
|
1048
|
+
throw new Error('content must be a post object.');
|
|
1049
|
+
const content = { ...args.content };
|
|
1050
|
+
if (content.mediaUrls !== undefined) {
|
|
1051
|
+
if (!Array.isArray(content.mediaUrls))
|
|
1052
|
+
throw new Error('content.mediaUrls must be an array.');
|
|
1053
|
+
content.mediaUrls = content.mediaUrls.map(socialImage);
|
|
1054
|
+
}
|
|
1055
|
+
args.content = content;
|
|
1056
|
+
}
|
|
1057
|
+
let result;
|
|
1058
|
+
if (name === 'get_social_workflow') {
|
|
1059
|
+
result = {
|
|
1060
|
+
supportedPlatforms: ['facebook', 'instagram'],
|
|
1061
|
+
connectUrl: 'https://codingmantra.com/tools/digital-marketing/social-media-hub',
|
|
1062
|
+
steps: ['list_social_accounts', 'generate_social_caption or write a caption with your assistant', 'generate an image with existing MCP tools or list_social_media', 'save_social_draft for review', 'schedule_social_post or publish_social_post as requested', 'list_social_posts / get_social_post / get_social_analytics'],
|
|
1063
|
+
limits: { instagram: { images: 1, captionIncludingHashtags: 2200 }, facebook: { maxImages: 10, captionIncludingHashtags: 63206 }, videoPublishing: false },
|
|
1064
|
+
timezone: 'Ask for the userβs intended timezone when ambiguous; convert to an ISO 8601 timestamp with an explicit UTC offset. Dates are returned as ISO 8601 UTC timestamps.',
|
|
1065
|
+
contentGuidance: 'Use a clear hook, useful verified facts, the intended audience and brand voice, and one CTA. Supply brandBrief to generate_social_caption for per-brand context. Never invent prices, claims, discounts, or business details. Caption generation uses credits; drafts and schedules do not run AI.',
|
|
1066
|
+
scheduling: 'The deployed backend requires its cron scheduler to run. The assistant does not need to remain online. Saved drafts are consumed atomically; reuse draftId to make repeated scheduling requests safe.',
|
|
1067
|
+
retries: 'Inspect failed post errors and publishedJobIds before rescheduling. Immediate publication has no idempotency guarantee; do not automatically retry ambiguous timeouts.',
|
|
1068
|
+
};
|
|
1069
|
+
}
|
|
1070
|
+
else {
|
|
1071
|
+
let endpoint = '';
|
|
1072
|
+
let method = 'GET';
|
|
1073
|
+
let body;
|
|
1074
|
+
if (name === 'list_social_accounts')
|
|
1075
|
+
endpoint = '/social/meta/connection';
|
|
1076
|
+
if (name === 'generate_social_caption') {
|
|
1077
|
+
endpoint = '/social/caption';
|
|
1078
|
+
method = 'POST';
|
|
1079
|
+
body = { caption: args.caption || '', brandBrief: args.brandBrief || '', mediaUrls: args.mediaUrls || [], platform: args.platform || 'instagram' };
|
|
1080
|
+
}
|
|
1081
|
+
if (name === 'list_social_drafts')
|
|
1082
|
+
endpoint = '/social/drafts' + socialQuery(args, ['offset']);
|
|
1083
|
+
if (name === 'save_social_draft') {
|
|
1084
|
+
endpoint = '/social/drafts';
|
|
1085
|
+
method = 'POST';
|
|
1086
|
+
body = args;
|
|
1087
|
+
}
|
|
1088
|
+
if (name === 'delete_social_draft') {
|
|
1089
|
+
endpoint = `/social/drafts?id=${socialId(args)}`;
|
|
1090
|
+
method = 'DELETE';
|
|
1091
|
+
}
|
|
1092
|
+
if (name === 'list_social_media')
|
|
1093
|
+
endpoint = '/social/gallery' + socialQuery({ ...args, type: 'image' }, ['type', 'page', 'limit']);
|
|
1094
|
+
if (name === 'schedule_social_post') {
|
|
1095
|
+
endpoint = '/social/schedule';
|
|
1096
|
+
method = 'POST';
|
|
1097
|
+
body = args;
|
|
1098
|
+
}
|
|
1099
|
+
if (name === 'list_social_posts')
|
|
1100
|
+
endpoint = '/social/schedule' + socialQuery(args, ['status', 'platform', 'fromDate', 'toDate', 'limit', 'offset']);
|
|
1101
|
+
if (['get_social_post', 'update_social_post', 'cancel_social_post', 'delete_social_post'].includes(name)) {
|
|
1102
|
+
endpoint = `/social/schedule/${socialId(args)}`;
|
|
1103
|
+
if (name === 'update_social_post') {
|
|
1104
|
+
method = 'PATCH';
|
|
1105
|
+
const { id: _id, ...updates } = args;
|
|
1106
|
+
body = updates;
|
|
1107
|
+
}
|
|
1108
|
+
if (name === 'cancel_social_post') {
|
|
1109
|
+
method = 'PATCH';
|
|
1110
|
+
body = { status: 'cancelled' };
|
|
1111
|
+
}
|
|
1112
|
+
if (name === 'delete_social_post')
|
|
1113
|
+
method = 'DELETE';
|
|
1114
|
+
}
|
|
1115
|
+
if (name === 'publish_social_post') {
|
|
1116
|
+
endpoint = '/social/meta/publish';
|
|
1117
|
+
method = 'POST';
|
|
1118
|
+
const caption = typeof args.caption === 'string' ? args.caption.trim() : '';
|
|
1119
|
+
if (args.hashtags !== undefined && (!Array.isArray(args.hashtags) || args.hashtags.some(tag => typeof tag !== 'string' || !/^#?[\p{L}\p{N}_]+$/u.test(tag))))
|
|
1120
|
+
throw new Error('Use valid hashtags containing letters, numbers, or underscores.');
|
|
1121
|
+
const existing = new Set((caption.match(/#[\p{L}\p{N}_]+/gu) || []).map(tag => tag.toLowerCase()));
|
|
1122
|
+
const tags = (args.hashtags || []).map(tag => `#${tag.replace(/^#/, '')}`).filter(tag => {
|
|
1123
|
+
if (existing.has(tag.toLowerCase()))
|
|
1124
|
+
return false;
|
|
1125
|
+
existing.add(tag.toLowerCase());
|
|
1126
|
+
return true;
|
|
1127
|
+
});
|
|
1128
|
+
const text = [caption, tags.join(' ')].filter(Boolean).join('\n\n');
|
|
1129
|
+
const images = args.mediaUrls || [];
|
|
1130
|
+
if (!['facebook', 'instagram'].includes(String(args.platform)))
|
|
1131
|
+
throw new Error('Choose Facebook or Instagram.');
|
|
1132
|
+
if (args.platform === 'instagram' && images.length !== 1)
|
|
1133
|
+
throw new Error('Instagram requires exactly one image.');
|
|
1134
|
+
body = args.platform === 'instagram'
|
|
1135
|
+
? { platform: 'instagram', instagramId: args.accountId, caption: text, imageDataUrl: images[0]?.startsWith('data:') ? images[0] : undefined, imageUrl: images[0]?.startsWith('https:') ? images[0] : undefined, socialContentId: args.socialContentId }
|
|
1136
|
+
: { platform: 'facebook', pageId: args.accountId, message: text, imageUrls: images.length ? images : undefined, link: args.link, socialContentId: args.socialContentId };
|
|
1137
|
+
}
|
|
1138
|
+
if (name === 'get_social_analytics')
|
|
1139
|
+
endpoint = '/social/analytics' + socialQuery(args, ['range', 'platform', 'accountId']);
|
|
1140
|
+
result = await apiClient(endpoint, { method, ...(body ? { body: JSON.stringify(body) } : {}) });
|
|
1141
|
+
}
|
|
1142
|
+
result = normalizeSocialDates(result);
|
|
1143
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], structuredContent: result, ...(result.success === false ? { isError: true } : {}) };
|
|
1144
|
+
}
|
|
577
1145
|
// βββ Tool Registration βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
578
1146
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
579
1147
|
return {
|
|
580
1148
|
tools: [
|
|
1149
|
+
...SOCIAL_TOOLS,
|
|
1150
|
+
GENERATE_JEWELLERY_RATE_POSTER_TOOL,
|
|
581
1151
|
GENERATE_PRODUCT_PHOTO_TOOL,
|
|
582
1152
|
GENERATE_LOGO_TOOL,
|
|
583
1153
|
TRY_ON_JEWELRY_TOOL,
|
|
584
1154
|
TRY_ON_APPAREL_TOOL,
|
|
585
1155
|
TRY_ON_PRODUCT_TOOL,
|
|
586
1156
|
GENERATE_FESTIVAL_POST_TOOL,
|
|
1157
|
+
BUILD_HUMAN_TOOL,
|
|
587
1158
|
GENERATE_YOUTUBE_THUMBNAIL_TOOL,
|
|
588
1159
|
GENERATE_PASSPORT_PHOTO_TOOL,
|
|
589
1160
|
SKETCH_TO_REAL_TOOL,
|
|
1161
|
+
EDIT_PROFESSIONAL_PHOTO_TOOL,
|
|
1162
|
+
EDIT_NANO_BANANA_TOOL,
|
|
1163
|
+
GENERATE_BLOG_IMAGE_TOOL,
|
|
1164
|
+
GENERATE_BABY_MILESTONE_TOOL,
|
|
590
1165
|
UPSCALE_IMAGE_TOOL,
|
|
591
1166
|
GENERATE_QR_CODE_TOOL,
|
|
592
1167
|
GENERATE_QR_CODE_SIMPLE_TOOL,
|
|
@@ -597,6 +1172,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
597
1172
|
GENERATE_FESTIVAL_VIDEO_TOOL,
|
|
598
1173
|
GENERATE_JEWELRY_VIDEO_TOOL,
|
|
599
1174
|
GENERATE_LOGO_VIDEO_TOOL,
|
|
1175
|
+
GENERATE_STORY_VIDEO_TOOL,
|
|
1176
|
+
GENERATE_TALKING_AVATAR_TOOL,
|
|
600
1177
|
CHECK_JOB_STATUS_TOOL,
|
|
601
1178
|
],
|
|
602
1179
|
};
|
|
@@ -605,7 +1182,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
605
1182
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
606
1183
|
try {
|
|
607
1184
|
const { name, arguments: rawArgs } = request.params;
|
|
1185
|
+
if (SOCIAL_TOOLS.some(tool => tool.name === name))
|
|
1186
|
+
return await executeSocialTool(name, rawArgs || {});
|
|
608
1187
|
const args = rawArgs || {};
|
|
1188
|
+
if (name === 'generate_jewellery_rate_poster') {
|
|
1189
|
+
const response = await apiClient('/image/jewellery-rate-poster', {
|
|
1190
|
+
method: 'POST',
|
|
1191
|
+
body: JSON.stringify({ ...args, productImage: resolveImageInput(args.productImage),
|
|
1192
|
+
logoImage: resolveImageInput(args.logoImage), outputResult: 'base64' }),
|
|
1193
|
+
});
|
|
1194
|
+
return formatImageToolResult(response, 'Jewellery Rate Poster Generated');
|
|
1195
|
+
}
|
|
609
1196
|
// ββ 1. Product Photography (synchronous) ββββββββββββββββββββββββββββββββββ
|
|
610
1197
|
if (name === 'generate_product_photo') {
|
|
611
1198
|
const payload = {
|
|
@@ -690,13 +1277,30 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
690
1277
|
});
|
|
691
1278
|
return formatImageToolResult(response, 'Festival Post Generated');
|
|
692
1279
|
}
|
|
693
|
-
// ββ 7.
|
|
1280
|
+
// ββ 7. Human Builder (synchronous) ββββββββββββββββββββββββββββββββββββββββ
|
|
1281
|
+
if (name === 'build_human') {
|
|
1282
|
+
const payload = {
|
|
1283
|
+
...args,
|
|
1284
|
+
referenceImages: Array.isArray(args.referenceImages)
|
|
1285
|
+
? args.referenceImages.map((img) => typeof img === 'string'
|
|
1286
|
+
? resolveImageInput(img)
|
|
1287
|
+
: resolveImageInput(img?.dataUrl || img?.path || img?.url))
|
|
1288
|
+
: undefined,
|
|
1289
|
+
};
|
|
1290
|
+
const response = await apiClient('/image/human-builder', {
|
|
1291
|
+
method: 'POST',
|
|
1292
|
+
body: JSON.stringify(payload),
|
|
1293
|
+
});
|
|
1294
|
+
return formatImageToolResult(response, 'AI Human Model Generated');
|
|
1295
|
+
}
|
|
1296
|
+
// ββ 8. YouTube Thumbnail (synchronous) ββββββββββββββββββββββββββββββββββββ
|
|
694
1297
|
if (name === 'generate_youtube_thumbnail') {
|
|
695
1298
|
const payload = {
|
|
696
1299
|
...args,
|
|
697
1300
|
personImage: resolveImageInput(args.personImage),
|
|
698
1301
|
backgroundImage: resolveImageInput(args.backgroundImage),
|
|
699
1302
|
logoImage: resolveImageInput(args.logoImage),
|
|
1303
|
+
referenceImage: resolveImageInput(args.referenceImage),
|
|
700
1304
|
};
|
|
701
1305
|
const response = await apiClient('/image/youtube-thumbnail-generator', {
|
|
702
1306
|
method: 'POST',
|
|
@@ -709,6 +1313,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
709
1313
|
const payload = {
|
|
710
1314
|
...args,
|
|
711
1315
|
photoDataUri: resolveImageInput(args.photoDataUri),
|
|
1316
|
+
referenceImage: resolveImageInput(args.referenceImage),
|
|
712
1317
|
};
|
|
713
1318
|
const response = await apiClient('/image/passport-photo', {
|
|
714
1319
|
method: 'POST',
|
|
@@ -730,7 +1335,72 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
730
1335
|
});
|
|
731
1336
|
return formatImageToolResult(response, 'Sketch-to-Real Image Generated');
|
|
732
1337
|
}
|
|
733
|
-
// ββ 10.
|
|
1338
|
+
// ββ 10. Professional Photography Editor (synchronous) βββββββββββββββββββββ
|
|
1339
|
+
if (name === 'edit_professional_photo') {
|
|
1340
|
+
let resolvedImages = args.images ? resolveImagesArray(args.images) : [];
|
|
1341
|
+
if (resolvedImages.length === 0 && args.image) {
|
|
1342
|
+
const single = resolveImageInput(args.image);
|
|
1343
|
+
if (single) {
|
|
1344
|
+
resolvedImages = [{ dataUrl: single }];
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
const payload = {
|
|
1348
|
+
...args,
|
|
1349
|
+
images: resolvedImages,
|
|
1350
|
+
referenceImage: resolveImageInput(args.referenceImage),
|
|
1351
|
+
};
|
|
1352
|
+
const response = await apiClient('/image/professional-photography-editor', {
|
|
1353
|
+
method: 'POST',
|
|
1354
|
+
body: JSON.stringify(payload),
|
|
1355
|
+
});
|
|
1356
|
+
return formatImageToolResult(response, 'Professional Photo Generated');
|
|
1357
|
+
}
|
|
1358
|
+
// ββ 11. Nano Banana Image Editor (synchronous) ββββββββββββββββββββββββββββ
|
|
1359
|
+
if (name === 'edit_nano_banana') {
|
|
1360
|
+
let resolvedImages = args.images ? resolveImagesArray(args.images) : [];
|
|
1361
|
+
if (resolvedImages.length === 0 && args.image) {
|
|
1362
|
+
const single = resolveImageInput(args.image);
|
|
1363
|
+
if (single) {
|
|
1364
|
+
resolvedImages = [{ dataUrl: single }];
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
const payload = {
|
|
1368
|
+
...args,
|
|
1369
|
+
images: resolvedImages,
|
|
1370
|
+
referenceImage: resolveImageInput(args.referenceImage),
|
|
1371
|
+
};
|
|
1372
|
+
const response = await apiClient('/image/nano-banana-editor', {
|
|
1373
|
+
method: 'POST',
|
|
1374
|
+
body: JSON.stringify(payload),
|
|
1375
|
+
});
|
|
1376
|
+
return formatImageToolResult(response, 'Nano Banana Image Generated');
|
|
1377
|
+
}
|
|
1378
|
+
// ββ 12. Blog Image Generator (synchronous) ββββββββββββββββββββββββββββββββ
|
|
1379
|
+
if (name === 'generate_blog_image') {
|
|
1380
|
+
const payload = {
|
|
1381
|
+
...args,
|
|
1382
|
+
referenceImage: resolveImageInput(args.referenceImage),
|
|
1383
|
+
};
|
|
1384
|
+
const response = await apiClient('/image/blog-image-generator', {
|
|
1385
|
+
method: 'POST',
|
|
1386
|
+
body: JSON.stringify(payload),
|
|
1387
|
+
});
|
|
1388
|
+
return formatImageToolResult(response, 'Blog Image Generated');
|
|
1389
|
+
}
|
|
1390
|
+
// ββ 13. Baby Milestone Generator (synchronous) βββββββββββββββββββββββββββ
|
|
1391
|
+
if (name === 'generate_baby_milestone') {
|
|
1392
|
+
const payload = {
|
|
1393
|
+
...args,
|
|
1394
|
+
photoDataUri: resolveImageInput(args.photoDataUri),
|
|
1395
|
+
referenceImage: resolveImageInput(args.referenceImage),
|
|
1396
|
+
};
|
|
1397
|
+
const response = await apiClient('/image/baby-milestone-generator', {
|
|
1398
|
+
method: 'POST',
|
|
1399
|
+
body: JSON.stringify(payload),
|
|
1400
|
+
});
|
|
1401
|
+
return formatImageToolResult(response, 'Baby Milestone Photo Generated');
|
|
1402
|
+
}
|
|
1403
|
+
// ββ 12. Upscale Image (synchronous) βββββββββββββββββββββββββββββββββββββββ
|
|
734
1404
|
if (name === 'upscale_image') {
|
|
735
1405
|
const payload = {
|
|
736
1406
|
...args,
|
|
@@ -739,6 +1409,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
739
1409
|
const response = await apiClient('/image/upscale-image', {
|
|
740
1410
|
method: 'POST',
|
|
741
1411
|
body: JSON.stringify(payload),
|
|
1412
|
+
signal: AbortSignal.timeout(12 * 60 * 1000),
|
|
742
1413
|
});
|
|
743
1414
|
return formatImageToolResult(response, 'Image Upscaled Successfully');
|
|
744
1415
|
}
|
|
@@ -798,14 +1469,27 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
798
1469
|
generate_apparel_video: '/apparel-video-generation',
|
|
799
1470
|
generate_festival_video: '/festival-video-generation',
|
|
800
1471
|
generate_jewelry_video: '/jewelry-video-generation',
|
|
801
|
-
generate_logo_video: '/logo-video-generation'
|
|
1472
|
+
generate_logo_video: '/logo-video-generation',
|
|
1473
|
+
generate_story_video: '/story-teller-generation',
|
|
1474
|
+
generate_talking_avatar: '/ai/talking-avatar/generate'
|
|
802
1475
|
};
|
|
803
1476
|
if (videoEndpoints[name]) {
|
|
804
|
-
const
|
|
1477
|
+
const optionalImage = (input) => typeof input === 'string' && input.trim()
|
|
1478
|
+
? resolveImageInput(input) : undefined;
|
|
1479
|
+
const references = Array.isArray(args.referenceImages)
|
|
1480
|
+
? args.referenceImages.map((reference) => ({
|
|
1481
|
+
...reference, image: resolveImageInput(reference.image)
|
|
1482
|
+
})) : undefined;
|
|
1483
|
+
const avatarImage = name === 'generate_talking_avatar' ? optionalImage(args.image) : undefined;
|
|
1484
|
+
if (name === 'generate_talking_avatar' && !/^data:image\/(png|jpeg|webp);base64,/.test(avatarImage || '')) {
|
|
1485
|
+
throw new Error('Talking Avatar requires a PNG, JPEG, or WebP portrait as a local file path or base64 data URI.');
|
|
1486
|
+
}
|
|
1487
|
+
const payload = name === 'generate_talking_avatar' ? { ...args, image: avatarImage } : {
|
|
805
1488
|
...args,
|
|
806
|
-
mainImage:
|
|
807
|
-
startImage:
|
|
808
|
-
endImage:
|
|
1489
|
+
mainImage: optionalImage(args.mainImage),
|
|
1490
|
+
startImage: optionalImage(args.startImage),
|
|
1491
|
+
endImage: optionalImage(args.endImage),
|
|
1492
|
+
referenceImages: references,
|
|
809
1493
|
};
|
|
810
1494
|
const response = await apiClient(videoEndpoints[name], {
|
|
811
1495
|
method: 'POST',
|
|
@@ -838,6 +1522,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
838
1522
|
text += `\nβ
**Video Ready:** [Watch / Download Video](${job.result.videoUrl})\n`;
|
|
839
1523
|
text += `\nπ **Gallery:** View in your [CodingMantra Gallery](https://codingmantra.com/my-gallery)`;
|
|
840
1524
|
}
|
|
1525
|
+
else if (job.status === 'cancelled') {
|
|
1526
|
+
text += `\nJob cancelled. No further polling is needed.`;
|
|
1527
|
+
}
|
|
841
1528
|
else if (job.status === 'failed') {
|
|
842
1529
|
text += `\nβ **Job Failed:** ${job.error || 'Unknown error occurred during generation.'}\n`;
|
|
843
1530
|
text += `Your credits have been refunded automatically.`;
|
|
@@ -862,7 +1549,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
862
1549
|
async function run() {
|
|
863
1550
|
const transport = new StdioServerTransport();
|
|
864
1551
|
await server.connect(transport);
|
|
865
|
-
console.error("[CodingMantra MCP] Server v0.
|
|
1552
|
+
console.error("[CodingMantra MCP] Server v0.3.0 initialized and running on stdio (43 tools active)");
|
|
866
1553
|
}
|
|
867
1554
|
run().catch((error) => {
|
|
868
1555
|
console.error("Fatal error running CodingMantra MCP server:", error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codingmantra/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Official Model Context Protocol (MCP) Server for CodingMantra AI Generation Tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
"build": "tsc",
|
|
17
17
|
"prepublishOnly": "npm run build",
|
|
18
18
|
"start": "node build/index.js",
|
|
19
|
-
"dev": "tsc --watch"
|
|
19
|
+
"dev": "tsc --watch",
|
|
20
|
+
"test": "npm run build && node --test tests/server.test.mjs"
|
|
20
21
|
},
|
|
21
22
|
"dependencies": {
|
|
22
|
-
"@modelcontextprotocol/sdk": "
|
|
23
|
+
"@modelcontextprotocol/sdk": "1.30.0",
|
|
23
24
|
"dotenv": "17.4.2",
|
|
24
25
|
"zod": "^3.23.8"
|
|
25
26
|
},
|