corent-mcp 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/server.js +27 -18
  2. package/package.json +1 -1
package/dist/server.js CHANGED
@@ -17,7 +17,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
17
17
  import { z } from "zod";
18
18
  import { MEDIA_WIDGET_HTML } from "./widget-html.js";
19
19
  export const DEFAULT_API_URL = "https://api.corent.tech";
20
- export const SERVER_VERSION = "0.5.0";
20
+ export const SERVER_VERSION = "0.5.2";
21
21
  // --- MCP Apps (SEP-1865): the media tools render an inline widget in hosts
22
22
  // that support it (claude.ai web/desktop, others). Hosts without the extension
23
23
  // ignore the _meta and fall back to plain text results, so this is additive.
@@ -179,11 +179,7 @@ export function createCorentServer(config = {}) {
179
179
  tier: z
180
180
  .enum(["air", "lite", "premium", "pro", "max_pro"])
181
181
  .optional()
182
- .describe("Quality tier (preferred): air=cheapest/fastest, lite=everyday, premium=production, pro=advanced, max_pro=maximum fidelity (flagship models). Overrides preference."),
183
- preference: z
184
- .enum(["fast", "cheap", "quality", "balanced"])
185
- .default("balanced")
186
- .describe("What to optimize for; Corent picks the best model tier automatically"),
182
+ .describe("Quality tier: air=cheapest (best value, not the quickest), lite=everyday, premium=production, pro=advanced, max_pro=maximum fidelity (flagship models). Omit for a sensible default."),
187
183
  style: z
188
184
  .enum(["photorealistic", "artistic", "anime", "logo", "text_focused"])
189
185
  .optional()
@@ -192,9 +188,9 @@ export function createCorentServer(config = {}) {
192
188
  },
193
189
  outputSchema: imageOutput,
194
190
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
195
- }, wrap(async ({ prompt, tier, preference, style, aspect_ratio }) => corent("/v1/images/generate", {
191
+ }, wrap(async ({ prompt, tier, style, aspect_ratio }) => corent("/v1/images/generate", {
196
192
  method: "POST",
197
- body: JSON.stringify({ prompt, tier, preference, style, aspect_ratio }),
193
+ body: JSON.stringify({ prompt, tier, style, aspect_ratio }),
198
194
  })));
199
195
  server.registerTool("generate_video", {
200
196
  title: "Generate video",
@@ -205,8 +201,7 @@ export function createCorentServer(config = {}) {
205
201
  tier: z
206
202
  .enum(["air", "lite", "premium", "pro", "max_pro"])
207
203
  .optional()
208
- .describe("Quality tier (preferred): air=cheapest/fastest, lite=everyday, premium=production, pro=advanced, max_pro=maximum fidelity (flagship models). Overrides preference."),
209
- preference: z.enum(["fast", "cheap", "quality", "balanced"]).default("balanced"),
204
+ .describe("Quality tier: air=cheapest (best value, not the quickest), lite=everyday, premium=production, pro=advanced, max_pro=maximum fidelity (flagship models). Omit for a sensible default."),
210
205
  aspect_ratio: z.enum(["16:9", "9:16", "1:1"]).default("16:9"),
211
206
  duration_s: z.number().int().min(1).max(30).optional().describe("Requested duration in seconds"),
212
207
  resolution: z
@@ -217,13 +212,13 @@ export function createCorentServer(config = {}) {
217
212
  },
218
213
  outputSchema: jobOutput,
219
214
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
220
- }, wrap(async ({ prompt, tier, preference, aspect_ratio, duration_s, resolution, image_url }) => corent("/v1/videos/generate", {
215
+ }, wrap(async ({ prompt, tier, aspect_ratio, duration_s, resolution, image_url }) => corent("/v1/videos/generate", {
221
216
  method: "POST",
222
- body: JSON.stringify({ prompt, tier, preference, aspect_ratio, duration_s, resolution, image_url }),
217
+ body: JSON.stringify({ prompt, tier, aspect_ratio, duration_s, resolution, image_url }),
223
218
  })));
224
219
  server.registerTool("generate_speech", {
225
220
  title: "Generate speech (voice)",
226
- description: "Generate spoken audio (text to speech) from text. Synchronous: returns the finished audio URL and the exact charge. Billed per 1,000 characters of input text (a few cents for a short narration). Failed generations are never billed.",
221
+ description: "Generate spoken audio (text to speech) from text. Synchronous: returns the finished audio URL and the exact charge. Billed in started blocks of 1,000 input characters, so even a one-sentence request bills the full first block (roughly 25-30 cents); longer scripts amortize better. Failed generations are never billed.",
227
222
  inputSchema: {
228
223
  text: z.string().min(1).max(5000).describe("The text to speak, max 5000 characters"),
229
224
  voice_id: z
@@ -263,7 +258,12 @@ export function createCorentServer(config = {}) {
263
258
  title: "Check service status",
264
259
  description: "Get live operational status of Corent's generation tiers (operational/degraded). Read-only and free; useful to pick a healthy tier.",
265
260
  inputSchema: {},
266
- outputSchema: { status: z.string().optional(), tiers: z.record(z.string(), z.any()).optional() },
261
+ // /v1/status returns tiers as an ARRAY of {name, status} — declaring it
262
+ // as a record made every call fail output validation (audit 2026-07-20).
263
+ outputSchema: {
264
+ status: z.string().optional(),
265
+ tiers: z.array(z.object({ name: z.string(), status: z.string() }).passthrough()).optional(),
266
+ },
267
267
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
268
268
  }, wrap(async () => corent("/v1/status")));
269
269
  // --- Intent tools: Corent's differentiator. Describe what you want in plain
@@ -303,9 +303,18 @@ export function createCorentServer(config = {}) {
303
303
  message: z.string().nullable().optional(),
304
304
  },
305
305
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
306
- }, wrap(async ({ intent, max_cost_cents }) => corent("/v1/intent/execute", {
307
- method: "POST",
308
- body: JSON.stringify({ intent, confirm_estimated_cost_cents_up_to: max_cost_cents }),
309
- })));
306
+ }, wrap(async ({ intent, max_cost_cents }) => {
307
+ const res = await corent("/v1/intent/execute", {
308
+ method: "POST",
309
+ body: JSON.stringify({ intent, confirm_estimated_cost_cents_up_to: max_cost_cents }),
310
+ });
311
+ // The API names the ceiling confirm_estimated_cost_cents_up_to; this tool
312
+ // exposes it as max_cost_cents. Translate the over-ceiling message so the
313
+ // agent is told to raise a parameter that actually exists here.
314
+ if (res && typeof res.message === "string") {
315
+ res.message = res.message.replace("confirm_estimated_cost_cents_up_to", "max_cost_cents");
316
+ }
317
+ return res;
318
+ }));
310
319
  return server;
311
320
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "corent-mcp",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "MCP server for the Corent media generation API — give any AI agent the ability to generate images and videos.",
5
5
  "mcpName": "io.github.gg13121/corent-mcp",
6
6
  "license": "MIT",