@codingmantra/mcp-server 0.4.0 → 0.5.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 +25 -6
- package/build/index.js +12 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,13 +2,21 @@
|
|
|
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.5.0
|
|
6
|
+
|
|
7
|
+
- Instagram supports single-image posts and ordered carousels of 2–10 images; Facebook supports up to 10 images in a multi-photo post.
|
|
8
|
+
- New `list_social_library` retrieves reusable complete posts with ordered slides, captions and usage filters. `list_social_media` retains generated-gallery access.
|
|
9
|
+
- Optional `mediaLayout` provides common square or portrait canvases using fit or crop, including reusable uploaded media IDs.
|
|
10
|
+
- Existing single-image publishing and scheduling inputs remain supported.
|
|
11
|
+
- Polling exposes processing details and delivery review flags. Never create a replacement post automatically when final delivery is uncertain.
|
|
12
|
+
|
|
13
|
+
## Previous v0.4.0 changes
|
|
6
14
|
|
|
7
15
|
- Social publishing and scheduling use the versioned developer API, supporting stable platform-prefixed account IDs, multiple targets, and caller-supplied idempotency keys.
|
|
8
16
|
- New `upload_social_image` and `get_social_image` tools support URL, base64, data URI, local files, and reusable media IDs.
|
|
9
17
|
- Per-account polling includes provider post IDs; cancellation retains delivery history. HTTP error codes and Retry-After are exposed in structured MCP errors.
|
|
10
18
|
- **Migration:** publication and scheduling inputs changed from the v0.3 platform/accountId or platforms/content shape to the contract below. Existing drafts, caption generation, analytics, and editing tools remain available.
|
|
11
|
-
- **Social media workflows:**
|
|
19
|
+
- **Social media workflows:** 19 tools for connected accounts, caption creation, drafts, gallery images, immediate publishing, scheduling, status, cancellation, and analytics. Uses the same CodingMantra API key.
|
|
12
20
|
|
|
13
21
|
- **Current API coverage:** Story Teller, HeyGen Talking Avatar IV, and Jewellery Rate Poster tools.
|
|
14
22
|
- **Video contract alignment:** Required prompt/model/duration/resolution/aspect ratio, character descriptions, seed, guidance, and local reference-image resolution.
|
|
@@ -16,7 +24,7 @@ The official **Model Context Protocol (MCP)** server connecting AI assistants (C
|
|
|
16
24
|
|
|
17
25
|
- 🖼️ **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.
|
|
18
26
|
- 📁 **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.
|
|
19
|
-
- ⚡ **Expanded Tool Suite (
|
|
27
|
+
- ⚡ **Expanded Tool Suite (47 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.
|
|
20
28
|
- 🎯 **Advanced Model & Resolution Parameters**: Direct support for `model`, `modelId`, `promptId`, custom reference images, and server-side credit synchronization.
|
|
21
29
|
- 🛡️ **Graceful Error Handling & 120s Timeout**: Informative error diagnostics when API keys are missing or requests time out, with clean stdio protocol execution.
|
|
22
30
|
|
|
@@ -24,7 +32,7 @@ The official **Model Context Protocol (MCP)** server connecting AI assistants (C
|
|
|
24
32
|
|
|
25
33
|
## Features & Tool Suite
|
|
26
34
|
|
|
27
|
-
The server exposes **
|
|
35
|
+
The server exposes **47 specialized generative, utility and social tools** over standard I/O (`stdio`):
|
|
28
36
|
|
|
29
37
|
### 1. Synchronous Image Generation (Immediate Inline Image Output)
|
|
30
38
|
- **`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.
|
|
@@ -96,7 +104,7 @@ Try: “Create three Facebook posts for my bakery’s launch. Use a warm voice a
|
|
|
96
104
|
|
|
97
105
|
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.
|
|
98
106
|
|
|
99
|
-
Instagram supports **
|
|
107
|
+
Instagram supports **1–10 images (one image or a carousel)**, 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.
|
|
100
108
|
|
|
101
109
|
Publishing and scheduling accept `accountIds` as one string or up to 20 distinct IDs from `list_social_accounts`, such as `facebook:123456` and `instagram:17890000000000000`. Account names are labels; use `platformAccountId` without its prefix only in existing draft/edit/analytics inputs. Those tools retain their legacy schemas.
|
|
102
110
|
|
|
@@ -123,7 +131,7 @@ Versioned social responses retain the REST `{data: ...}` envelope in MCP text an
|
|
|
123
131
|
|
|
124
132
|
Limits are shared across keys per user: 300 reads and 60 writes per minute. API failures provide structured `error.code`, `error.status`, and optional `error.retryAfter` alongside text. Wait for Retry-After on 429 or request-in-progress conflicts; no automatic retry is performed by the MCP server.
|
|
125
133
|
|
|
126
|
-
Deployment order: deploy the updated web API and Firestore rules, verify the cron worker, then release/use MCP v0.
|
|
134
|
+
Deployment order: deploy the updated web API and Firestore rules, verify the cron worker, then release/use MCP v0.5.0. The package version here is prepared locally; updating source does not publish npm. See [social API documentation](https://codingmantra.com/api-docs/social-media), [OpenAPI contract](https://codingmantra.com/openapi/social-media.json), and repository `docs/social-mcp-api.md`.
|
|
127
135
|
|
|
128
136
|
|
|
129
137
|
## Video parameters
|
|
@@ -252,3 +260,14 @@ CODINGMANTRA_API_KEY=your_key node build/index.js
|
|
|
252
260
|
Private & Proprietary — Part of the CodingMantra Web Portal © 2026. All rights reserved.
|
|
253
261
|
|
|
254
262
|
MCP transport note: the server accepts messages up to 24 MB so base64 images within the 20 MB API JSON limit fit with the MCP envelope. Individual clients may impose smaller message limits; use local paths, direct HTTPS URLs, and reusable media IDs in that case. Larger messages exceed the transport bound and can close the connection.
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
### Ordered carousels and the Content Library
|
|
266
|
+
|
|
267
|
+
Instagram accepts one image or 2–10 ordered carousel slides. Facebook accepts up to 10 images as a multi-photo feed post; its presentation is controlled by Facebook and may differ from an Instagram slider. Existing single-image requests and `mediaUrl` content remain supported. The first image is the cover. A carousel counts as one published Instagram post; publishing quota is per Instagram account in a rolling 24-hour window, read from Meta's `content_publishing_limit` response rather than assumed globally.
|
|
268
|
+
|
|
269
|
+
`POST /api/v1/social/posts` and MCP `publish_social_post` / `schedule_social_post` accept ordered `images` and optional `mediaLayout`: `original`, `square-fit`, `square-crop`, `portrait-fit`, or `portrait-crop`. Fit preserves the complete image with white padding; crop fills a common canvas. Uploaded media IDs also support canvas conversion. Use the same idempotency key and unchanged body on retry. Post responses include `postType`, `imageCount`, `coverImage`, `processingMessage`, `deliveryNeedsReview`, and per-account publication `permalink`. A queued response confirms acceptance; poll `get_social_post` until delivery completes. When `deliveryNeedsReview` is true, inspect the account before intentionally creating another post; do not automatically retry with a new key.
|
|
270
|
+
|
|
271
|
+
`GET /api/v1/social/library` (API-key authentication) and MCP `list_social_library` return `{ data: { items, total, hasMore } }`. Each item includes `mediaUrl` (cover), ordered `mediaUrls`, `type` (`image`, `carousel`, or `video`), caption, hashtags, usage, and statuses. Filters: `groupBy=post|media` (default `post`), `status=unused|scheduled|published`, `type`, `platform`, raw `accountId` (requires platform), `search`, `offset`, and `limit` (1–100, default 24). `list_social_media` continues to read the generated-image gallery. This library is read-only; reuse creates a new post.
|
|
272
|
+
|
|
273
|
+
The Hub Content Library defaults to Posts, displays slide counts, opens every slide in a navigable preview, and reuses all images in order. Individual media retains the existing deduplicated asset view. The session-authenticated `/api/social/library` defaults to `groupBy=media` for compatibility; the Hub explicitly requests `post`. Saved content POST/PATCH supports `mediaUrls` (1–10), maintains scalar `mediaUrl` as the cover, and stores multi-image records as `carousel`.
|
package/build/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { apiClient, CodingMantraApiError } from './api-client.js';
|
|
|
7
7
|
import { formatImageToolResult, resolveImageInput, resolveImagesArray } from './image-utils.js';
|
|
8
8
|
const server = new Server({
|
|
9
9
|
name: "codingmantra-mcp",
|
|
10
|
-
version: "0.
|
|
10
|
+
version: "0.5.0",
|
|
11
11
|
}, {
|
|
12
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 platform-prefixed account IDs, a stable caller-chosen idempotencyKey for each intended post, and explicit timezone offsets. Publication is asynchronous; poll get_social_post and never claim a queued post is live. Only Facebook Pages and Instagram image posts are supported. Keep social provider tokens on the backend.",
|
|
13
13
|
capabilities: {
|
|
@@ -647,11 +647,11 @@ const EDIT_NANO_BANANA_TOOL = {
|
|
|
647
647
|
},
|
|
648
648
|
model: {
|
|
649
649
|
type: "string",
|
|
650
|
-
description: "Model tier ('flash', 'pro', 'standard'). Default is 'flash' (google/gemini-3.1-flash-image)."
|
|
650
|
+
description: "Model tier ('flash', 'pro', 'standard', 'gemini-nano-banana-2.1', 'hy-image-v3.5-preview'). Default is 'flash' (google/gemini-3.1-flash-image)."
|
|
651
651
|
},
|
|
652
652
|
modelId: {
|
|
653
653
|
type: "string",
|
|
654
|
-
description: "The image model ID."
|
|
654
|
+
description: "The image model ID (e.g. 'tencent/hy-image-v3.5-preview', 'google/gemini-nano-banana-2.1', 'google/gemini-3.1-flash-image')."
|
|
655
655
|
},
|
|
656
656
|
resolution: {
|
|
657
657
|
type: "string",
|
|
@@ -954,9 +954,10 @@ const SOCIAL_ACCOUNT_SCHEMA = {
|
|
|
954
954
|
};
|
|
955
955
|
const SOCIAL_CONTENT_PROPERTIES = {
|
|
956
956
|
caption: { type: 'string', maxLength: 63206, description: 'Post text. Instagram caption plus hashtags must fit 2200 characters.' },
|
|
957
|
+
mediaLayout: { type: 'string', enum: ['original', 'square-fit', 'square-crop', 'portrait-fit', 'portrait-crop'], description: 'Apply the same canvas to all slides; fit preserves the full image with white padding, crop fills the canvas.' },
|
|
957
958
|
brandBrief: { type: 'string', maxLength: 4000, description: 'Brand name, audience, voice, offer, facts, and call to action for this post.' },
|
|
958
959
|
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
|
|
960
|
+
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 supports one image or a carousel of 2–10 images; Facebook accepts up to 10.' },
|
|
960
961
|
};
|
|
961
962
|
const SOCIAL_SCHEDULE_PROPERTIES = {
|
|
962
963
|
draftId: { type: 'string', description: 'Optional saved draft ID. Scheduling consumes it atomically; repeating this request returns the same scheduled post.' },
|
|
@@ -980,9 +981,10 @@ const SOCIAL_POST_PROPERTIES = {
|
|
|
980
981
|
{ type: 'string', pattern: '^(facebook|instagram):[0-9]+$', description: 'One platform-prefixed connected account ID.' },
|
|
981
982
|
{ type: 'array', minItems: 1, maxItems: 20, uniqueItems: true, items: { type: 'string', pattern: '^(facebook|instagram):[0-9]+$', description: 'Platform-prefixed connected account ID.' } },
|
|
982
983
|
] },
|
|
984
|
+
mediaLayout: SOCIAL_CONTENT_PROPERTIES.mediaLayout,
|
|
983
985
|
caption: SOCIAL_CONTENT_PROPERTIES.caption,
|
|
984
986
|
hashtags: SOCIAL_CONTENT_PROPERTIES.hashtags,
|
|
985
|
-
images: { type: 'array', maxItems: 10, items: SOCIAL_API_IMAGE, description: 'Image inputs; Instagram requires
|
|
987
|
+
images: { type: 'array', maxItems: 10, items: SOCIAL_API_IMAGE, description: 'Image inputs; Instagram requires 1–10 images (single image or carousel). Use reusable mediaId for large images.' },
|
|
986
988
|
idempotencyKey: { type: 'string', minLength: 8, maxLength: 128, pattern: '^[A-Za-z0-9._:-]+$', description: 'Caller-chosen key for this intended post. Preserve the exact key and body on retries; a new key means a new post. Never invent a new key after a timeout.' },
|
|
987
989
|
};
|
|
988
990
|
const SOCIAL_ID = { type: 'string', minLength: 1, pattern: '^[A-Za-z0-9_-]+$', description: 'Exact draft, media UUID or post ID returned by a social tool.' };
|
|
@@ -996,6 +998,7 @@ const SOCIAL_TOOLS = [
|
|
|
996
998
|
{ 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.' } } } },
|
|
997
999
|
{ 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.' } } } },
|
|
998
1000
|
{ 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'] } },
|
|
1001
|
+
{ name: 'list_social_library', description: 'Read reusable saved content and scheduled/published posts with ordered slides. Defaults to grouped posts; groupBy media returns individual assets. Read-only.', annotations: socialRead, inputSchema: { type: 'object', properties: { groupBy: { type: 'string', enum: ['post', 'media'] }, status: { type: 'string', enum: ['unused', 'scheduled', 'published'] }, type: { type: 'string', enum: ['image', 'carousel', 'video'] }, platform: { type: 'string', enum: ['facebook', 'instagram'] }, accountId: { type: 'string', description: 'Raw platform account ID; requires platform.' }, search: { type: 'string', maxLength: 200 }, offset: { type: 'integer', minimum: 0 }, limit: { type: 'integer', minimum: 1, maximum: 100 } } } },
|
|
999
1002
|
{ 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).' } } } },
|
|
1000
1003
|
{ name: 'upload_social_image', description: 'Synchronously upload and normalize an image from HTTPS URL, base64, data URI, or local file. Returns an owner-scoped reusable media ID and JPEG URL; does not publish or generate AI content. Source max 10 MB/40 million pixels; request max 20 MB.', annotations: socialWrite, inputSchema: { type: 'object', additionalProperties: false, properties: { image: { ...SOCIAL_API_IMAGE, oneOf: SOCIAL_API_IMAGE.oneOf.slice(0, 4) } }, required: ['image'] } },
|
|
1001
1004
|
{ name: 'get_social_image', description: 'Read prepared image metadata by reusable media UUID. Read-only and scoped to your API-key owner.', annotations: socialRead, inputSchema: { type: 'object', additionalProperties: false, properties: { id: { type: 'string', format: 'uuid', description: 'Media UUID returned by upload_social_image.' } }, required: ['id'] } },
|
|
@@ -1096,7 +1099,7 @@ async function executeSocialTool(name, rawArgs) {
|
|
|
1096
1099
|
supportedPlatforms: ['facebook', 'instagram'],
|
|
1097
1100
|
connectUrl: 'https://codingmantra.com/tools/digital-marketing/social-media-hub',
|
|
1098
1101
|
steps: ['list_social_accounts', 'generate_social_caption or write a caption with your assistant', 'generate an image, list_social_media, or upload_social_image for a reusable mediaId', 'save_social_draft for review', 'schedule_social_post or publish_social_post as requested; schedule_social_draft for an approved saved draft', 'list_social_posts / get_social_post / get_social_analytics'],
|
|
1099
|
-
limits: { instagram: {
|
|
1102
|
+
limits: { instagram: { minImages: 1, maxImages: 10, carousel: true, captionIncludingHashtags: 2200 }, facebook: { minImages: 0, maxImages: 10, multiPhoto: true, captionIncludingHashtags: 63206 }, videoPublishing: false },
|
|
1100
1103
|
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.',
|
|
1101
1104
|
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.',
|
|
1102
1105
|
accountIds: 'Use accounts[].id for publishing/scheduling (facebook:123 or instagram:456); draft/edit/analytics tools use the raw platformAccountId plus platform.',
|
|
@@ -1130,6 +1133,8 @@ async function executeSocialTool(name, rawArgs) {
|
|
|
1130
1133
|
endpoint = `/social/drafts?id=${socialId(args)}`;
|
|
1131
1134
|
method = 'DELETE';
|
|
1132
1135
|
}
|
|
1136
|
+
if (name === 'list_social_library')
|
|
1137
|
+
endpoint = '/v1/social/library' + socialQuery(args, ['groupBy', 'status', 'type', 'platform', 'accountId', 'search', 'offset', 'limit']);
|
|
1133
1138
|
if (name === 'list_social_media')
|
|
1134
1139
|
endpoint = '/social/gallery' + socialQuery({ ...args, type: 'image' }, ['type', 'page', 'limit']);
|
|
1135
1140
|
if (name === 'schedule_social_draft') {
|
|
@@ -1590,7 +1595,7 @@ async function run() {
|
|
|
1590
1595
|
// API JSON limit plus the MCP request envelope, while still bounding input.
|
|
1591
1596
|
const transport = new StdioServerTransport(process.stdin, process.stdout, { maxBufferSize: 24 * 1024 * 1024 });
|
|
1592
1597
|
await server.connect(transport);
|
|
1593
|
-
console.error("[CodingMantra MCP] Server v0.
|
|
1598
|
+
console.error("[CodingMantra MCP] Server v0.5.0 initialized and running on stdio (47 tools active)");
|
|
1594
1599
|
}
|
|
1595
1600
|
run().catch((error) => {
|
|
1596
1601
|
console.error("Fatal error running CodingMantra MCP server:", error);
|
package/package.json
CHANGED