corent-mcp 0.2.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 +47 -0
- package/dist/index.js +89 -0
- package/package.json +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Corent MCP Server
|
|
2
|
+
|
|
3
|
+
Give any AI agent the ability to generate images and videos through the [Corent](https://corent.tech) API — one key, automatic model routing, provider fallback built in.
|
|
4
|
+
|
|
5
|
+
## Tools
|
|
6
|
+
|
|
7
|
+
| Tool | What it does |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `plan` | Describe a request in plain language; Corent returns the plan (image vs video, tier, settings) + cost estimate, without generating |
|
|
10
|
+
| `create` | Describe what you want + a spend ceiling; Corent decides everything and generates it (the "zero decisions" path) |
|
|
11
|
+
| `generate_image` | Text → image, synchronous, returns a permanent URL |
|
|
12
|
+
| `generate_video` | Text (or image) → video, async job |
|
|
13
|
+
| `get_job` | Poll a job until completed |
|
|
14
|
+
| `get_balance` | Remaining account balance |
|
|
15
|
+
| `get_status` | Live tier health |
|
|
16
|
+
|
|
17
|
+
The **`plan`** and **`create`** tools are the agent-native path: an agent says
|
|
18
|
+
what it wants ("a 10s vertical clip of a sunrise for TikTok") and Corent picks
|
|
19
|
+
image-vs-video, the tier, aspect ratio, and duration — the agent never manages
|
|
20
|
+
models. `create` enforces a per-call spend ceiling so an autonomous agent can't
|
|
21
|
+
overspend.
|
|
22
|
+
|
|
23
|
+
## Setup
|
|
24
|
+
|
|
25
|
+
Get an API key at [corent.tech](https://corent.tech), then add to your MCP client config:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"mcpServers": {
|
|
30
|
+
"corent": {
|
|
31
|
+
"command": "npx",
|
|
32
|
+
"args": ["-y", "corent-mcp"],
|
|
33
|
+
"env": { "CORENT_API_KEY": "co_live_..." }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For Claude Code: `claude mcp add corent -e CORENT_API_KEY=co_live_... -- npx -y corent-mcp`
|
|
40
|
+
|
|
41
|
+
## Development
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npm install
|
|
45
|
+
npm run build
|
|
46
|
+
CORENT_API_KEY=... node dist/index.js
|
|
47
|
+
```
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Corent MCP server — exposes the Corent media generation API
|
|
4
|
+
* (https://corent.tech) as tools any MCP-compatible agent can call.
|
|
5
|
+
*
|
|
6
|
+
* Auth: set CORENT_API_KEY in the environment.
|
|
7
|
+
* Optional: CORENT_API_URL to point at a different API host.
|
|
8
|
+
*/
|
|
9
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
const API_URL = process.env.CORENT_API_URL ?? "https://corent-api.fly.dev";
|
|
13
|
+
const API_KEY = process.env.CORENT_API_KEY;
|
|
14
|
+
if (!API_KEY) {
|
|
15
|
+
console.error("CORENT_API_KEY environment variable is required. Get a key at https://corent.tech");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
async function corent(path, init) {
|
|
19
|
+
const res = await fetch(`${API_URL}${path}`, {
|
|
20
|
+
...init,
|
|
21
|
+
headers: {
|
|
22
|
+
Authorization: `Bearer ${API_KEY}`,
|
|
23
|
+
"Content-Type": "application/json",
|
|
24
|
+
...init?.headers,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
const body = await res.json().catch(() => ({}));
|
|
28
|
+
if (!res.ok) {
|
|
29
|
+
throw new Error(`Corent API ${res.status}: ${JSON.stringify(body.detail ?? body)}`);
|
|
30
|
+
}
|
|
31
|
+
return body;
|
|
32
|
+
}
|
|
33
|
+
function textResult(data) {
|
|
34
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
35
|
+
}
|
|
36
|
+
const server = new McpServer({ name: "corent", version: "0.2.0" });
|
|
37
|
+
server.tool("generate_image", "Generate an image from a text prompt. Returns a permanent public URL. Synchronous: typically completes in 2-20 seconds. Costs a few cents, billed to the Corent account.", {
|
|
38
|
+
prompt: z.string().describe("What to generate, in plain language"),
|
|
39
|
+
preference: z
|
|
40
|
+
.enum(["fast", "cheap", "quality", "balanced"])
|
|
41
|
+
.default("balanced")
|
|
42
|
+
.describe("What to optimize for; Corent picks the best model tier automatically"),
|
|
43
|
+
style: z
|
|
44
|
+
.enum(["photorealistic", "artistic", "anime", "logo", "text_focused"])
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("Optional content style hint"),
|
|
47
|
+
aspect_ratio: z.enum(["1:1", "16:9", "9:16", "4:3", "3:4"]).default("1:1"),
|
|
48
|
+
}, async ({ prompt, preference, style, aspect_ratio }) => {
|
|
49
|
+
const data = await corent("/v1/images/generate", {
|
|
50
|
+
method: "POST",
|
|
51
|
+
body: JSON.stringify({ prompt, preference, style, aspect_ratio }),
|
|
52
|
+
});
|
|
53
|
+
return textResult(data);
|
|
54
|
+
});
|
|
55
|
+
server.tool("generate_video", "Start generating a video from a text prompt (optionally animating a source image). Asynchronous: returns a job id immediately; poll get_job until status is 'completed'. Video costs more than images (tens of cents to a few dollars depending on tier).", {
|
|
56
|
+
prompt: z.string().describe("What to generate, in plain language"),
|
|
57
|
+
preference: z.enum(["fast", "cheap", "quality", "balanced"]).default("balanced"),
|
|
58
|
+
aspect_ratio: z.enum(["16:9", "9:16", "1:1"]).default("16:9"),
|
|
59
|
+
duration_s: z.number().int().min(1).max(30).optional().describe("Requested duration in seconds"),
|
|
60
|
+
image_url: z.string().url().optional().describe("If set, animates this image instead of pure text-to-video"),
|
|
61
|
+
}, async ({ prompt, preference, aspect_ratio, duration_s, image_url }) => {
|
|
62
|
+
const data = await corent("/v1/videos/generate", {
|
|
63
|
+
method: "POST",
|
|
64
|
+
body: JSON.stringify({ prompt, preference, aspect_ratio, duration_s, image_url }),
|
|
65
|
+
});
|
|
66
|
+
return textResult(data);
|
|
67
|
+
});
|
|
68
|
+
server.tool("get_job", "Check the status of a generation job (mainly videos). When completed, the response includes the permanent media URL and the cost.", { job_id: z.string().describe("The job id returned by generate_video or generate_image") }, async ({ job_id }) => textResult(await corent(`/v1/jobs/${job_id}`)));
|
|
69
|
+
server.tool("get_balance", "Get the Corent account's remaining balance in cents. Useful before starting expensive video generations.", {}, async () => textResult(await corent("/v1/account/balance")));
|
|
70
|
+
server.tool("get_status", "Get live operational status of Corent's generation tiers (operational/degraded). No auth cost; useful to pick a healthy tier.", {}, async () => textResult(await corent("/v1/status")));
|
|
71
|
+
// --- Intent tools: Corent's differentiator. Describe what you want in plain
|
|
72
|
+
// language; Corent decides image-vs-video, tier, aspect ratio, and cleans the
|
|
73
|
+
// prompt. The agent never picks a model or tier. ---
|
|
74
|
+
server.tool("plan", "Preview how Corent would handle a plain-language request WITHOUT generating anything (costs a fraction of a cent). Corent decides whether it's an image or video, which tier, aspect ratio, and duration, and returns the plan plus an estimated cost. Use this to decide or confirm cost before spending. If the request is something Corent can't generate (audio, text, 3D, editing, real-world actions), can_fulfill is false with a reason.", {
|
|
75
|
+
intent: z.string().describe("What you want, in natural language, e.g. 'a 10s vertical clip of a sunrise for TikTok'"),
|
|
76
|
+
}, async ({ intent }) => textResult(await corent("/v1/intent", { method: "POST", body: JSON.stringify({ intent }) })));
|
|
77
|
+
server.tool("create", "Describe what you want in plain language and Corent plans AND generates it — choosing image vs video, tier, aspect ratio, and duration for you (the 'zero decisions' path). You MUST pass max_cost_cents as a spend ceiling; if the estimated cost exceeds it, nothing is generated and you're told the estimate so you can raise the ceiling. Image results come back with a URL; video results come back as a job id to poll with get_job.", {
|
|
78
|
+
intent: z.string().describe("What you want, in natural language"),
|
|
79
|
+
max_cost_cents: z
|
|
80
|
+
.number()
|
|
81
|
+
.int()
|
|
82
|
+
.min(1)
|
|
83
|
+
.describe("Spend ceiling in cents for this one generation. Corent refuses if the estimate is higher."),
|
|
84
|
+
}, async ({ intent, max_cost_cents }) => textResult(await corent("/v1/intent/execute", {
|
|
85
|
+
method: "POST",
|
|
86
|
+
body: JSON.stringify({ intent, confirm_estimated_cost_cents_up_to: max_cost_cents }),
|
|
87
|
+
})));
|
|
88
|
+
const transport = new StdioServerTransport();
|
|
89
|
+
await server.connect(transport);
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "corent-mcp",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "MCP server for the Corent media generation API — give any AI agent the ability to generate images and videos.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"corent-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc && chmod +x dist/index.js",
|
|
15
|
+
"start": "node dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"mcp",
|
|
19
|
+
"modelcontextprotocol",
|
|
20
|
+
"image-generation",
|
|
21
|
+
"video-generation",
|
|
22
|
+
"ai-agents",
|
|
23
|
+
"corent"
|
|
24
|
+
],
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
27
|
+
"zod": "^3.23.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"typescript": "^5.6.0",
|
|
31
|
+
"@types/node": "^22.0.0"
|
|
32
|
+
}
|
|
33
|
+
}
|