@evolinkai/mcp 0.0.0-stage → 1.4.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/LICENSE +178 -0
- package/README.md +67 -2
- package/dist/core/src/branding.d.ts +3 -0
- package/dist/core/src/branding.d.ts.map +1 -0
- package/dist/core/src/branding.js +8 -0
- package/dist/core/src/branding.js.map +1 -0
- package/dist/core/src/config.d.ts +19 -0
- package/dist/core/src/config.d.ts.map +1 -0
- package/dist/core/src/config.js +90 -0
- package/dist/core/src/config.js.map +1 -0
- package/dist/core/src/data/model-params.d.ts +49 -0
- package/dist/core/src/data/model-params.d.ts.map +1 -0
- package/dist/core/src/data/model-params.generated.d.ts +2 -0
- package/dist/core/src/data/model-params.generated.d.ts.map +1 -0
- package/dist/core/src/data/model-params.generated.js +3 -0
- package/dist/core/src/data/model-params.generated.js.map +1 -0
- package/dist/core/src/data/model-params.js +22 -0
- package/dist/core/src/data/model-params.js.map +1 -0
- package/dist/core/src/request-context.d.ts +79 -0
- package/dist/core/src/request-context.d.ts.map +1 -0
- package/dist/core/src/request-context.js +52 -0
- package/dist/core/src/request-context.js.map +1 -0
- package/dist/core/src/server.d.ts +36 -0
- package/dist/core/src/server.d.ts.map +1 -0
- package/dist/core/src/server.js +123 -0
- package/dist/core/src/server.js.map +1 -0
- package/dist/core/src/services/api-client.d.ts +142 -0
- package/dist/core/src/services/api-client.d.ts.map +1 -0
- package/dist/core/src/services/api-client.js +179 -0
- package/dist/core/src/services/api-client.js.map +1 -0
- package/dist/core/src/services/error-handler.d.ts +51 -0
- package/dist/core/src/services/error-handler.d.ts.map +1 -0
- package/dist/core/src/services/error-handler.js +403 -0
- package/dist/core/src/services/error-handler.js.map +1 -0
- package/dist/core/src/services/file-client.d.ts +54 -0
- package/dist/core/src/services/file-client.d.ts.map +1 -0
- package/dist/core/src/services/file-client.js +131 -0
- package/dist/core/src/services/file-client.js.map +1 -0
- package/dist/core/src/services/http-policy.d.ts +40 -0
- package/dist/core/src/services/http-policy.d.ts.map +1 -0
- package/dist/core/src/services/http-policy.js +120 -0
- package/dist/core/src/services/http-policy.js.map +1 -0
- package/dist/core/src/services/media-preview.d.ts +24 -0
- package/dist/core/src/services/media-preview.d.ts.map +1 -0
- package/dist/core/src/services/media-preview.js +155 -0
- package/dist/core/src/services/media-preview.js.map +1 -0
- package/dist/core/src/services/model-catalog.d.ts +24 -0
- package/dist/core/src/services/model-catalog.d.ts.map +1 -0
- package/dist/core/src/services/model-catalog.js +45 -0
- package/dist/core/src/services/model-catalog.js.map +1 -0
- package/dist/core/src/services/param-validator.d.ts +21 -0
- package/dist/core/src/services/param-validator.d.ts.map +1 -0
- package/dist/core/src/services/param-validator.js +164 -0
- package/dist/core/src/services/param-validator.js.map +1 -0
- package/dist/core/src/services/preview-download.d.ts +11 -0
- package/dist/core/src/services/preview-download.d.ts.map +1 -0
- package/dist/core/src/services/preview-download.js +106 -0
- package/dist/core/src/services/preview-download.js.map +1 -0
- package/dist/core/src/services/pricing-client.d.ts +95 -0
- package/dist/core/src/services/pricing-client.d.ts.map +1 -0
- package/dist/core/src/services/pricing-client.js +396 -0
- package/dist/core/src/services/pricing-client.js.map +1 -0
- package/dist/core/src/services/upload-policy.d.ts +19 -0
- package/dist/core/src/services/upload-policy.d.ts.map +1 -0
- package/dist/core/src/services/upload-policy.js +168 -0
- package/dist/core/src/services/upload-policy.js.map +1 -0
- package/dist/core/src/services/upload-slots.d.ts +63 -0
- package/dist/core/src/services/upload-slots.d.ts.map +1 -0
- package/dist/core/src/services/upload-slots.js +24 -0
- package/dist/core/src/services/upload-slots.js.map +1 -0
- package/dist/core/src/services/utm.d.ts +29 -0
- package/dist/core/src/services/utm.d.ts.map +1 -0
- package/dist/core/src/services/utm.js +64 -0
- package/dist/core/src/services/utm.js.map +1 -0
- package/dist/core/src/tool-guidance.d.ts +6 -0
- package/dist/core/src/tool-guidance.d.ts.map +1 -0
- package/dist/core/src/tool-guidance.js +49 -0
- package/dist/core/src/tool-guidance.js.map +1 -0
- package/dist/core/src/tools/check-balance.d.ts +4 -0
- package/dist/core/src/tools/check-balance.d.ts.map +1 -0
- package/dist/core/src/tools/check-balance.js +82 -0
- package/dist/core/src/tools/check-balance.js.map +1 -0
- package/dist/core/src/tools/estimate-cost.d.ts +4 -0
- package/dist/core/src/tools/estimate-cost.d.ts.map +1 -0
- package/dist/core/src/tools/estimate-cost.js +131 -0
- package/dist/core/src/tools/estimate-cost.js.map +1 -0
- package/dist/core/src/tools/generate.d.ts +4 -0
- package/dist/core/src/tools/generate.d.ts.map +1 -0
- package/dist/core/src/tools/generate.js +221 -0
- package/dist/core/src/tools/generate.js.map +1 -0
- package/dist/core/src/tools/get-model.d.ts +5 -0
- package/dist/core/src/tools/get-model.d.ts.map +1 -0
- package/dist/core/src/tools/get-model.js +117 -0
- package/dist/core/src/tools/get-model.js.map +1 -0
- package/dist/core/src/tools/get-task.d.ts +7 -0
- package/dist/core/src/tools/get-task.d.ts.map +1 -0
- package/dist/core/src/tools/get-task.js +56 -0
- package/dist/core/src/tools/get-task.js.map +1 -0
- package/dist/core/src/tools/list-tasks.d.ts +6 -0
- package/dist/core/src/tools/list-tasks.d.ts.map +1 -0
- package/dist/core/src/tools/list-tasks.js +149 -0
- package/dist/core/src/tools/list-tasks.js.map +1 -0
- package/dist/core/src/tools/prepare-upload.d.ts +6 -0
- package/dist/core/src/tools/prepare-upload.d.ts.map +1 -0
- package/dist/core/src/tools/prepare-upload.js +134 -0
- package/dist/core/src/tools/prepare-upload.js.map +1 -0
- package/dist/core/src/tools/search-models.d.ts +5 -0
- package/dist/core/src/tools/search-models.d.ts.map +1 -0
- package/dist/core/src/tools/search-models.js +97 -0
- package/dist/core/src/tools/search-models.js.map +1 -0
- package/dist/core/src/tools/shared.d.ts +55 -0
- package/dist/core/src/tools/shared.d.ts.map +1 -0
- package/dist/core/src/tools/shared.js +137 -0
- package/dist/core/src/tools/shared.js.map +1 -0
- package/dist/core/src/tools/task-format.d.ts +48 -0
- package/dist/core/src/tools/task-format.d.ts.map +1 -0
- package/dist/core/src/tools/task-format.js +212 -0
- package/dist/core/src/tools/task-format.js.map +1 -0
- package/dist/core/src/tools/upload-file.d.ts +17 -0
- package/dist/core/src/tools/upload-file.d.ts.map +1 -0
- package/dist/core/src/tools/upload-file.js +134 -0
- package/dist/core/src/tools/upload-file.js.map +1 -0
- package/dist/core/src/version.d.ts +3 -0
- package/dist/core/src/version.d.ts.map +1 -0
- package/dist/core/src/version.js +3 -0
- package/dist/core/src/version.js.map +1 -0
- package/dist/evolink-media/src/index.d.ts +3 -0
- package/dist/evolink-media/src/index.d.ts.map +1 -0
- package/dist/evolink-media/src/index.js +18 -0
- package/dist/evolink-media/src/index.js.map +1 -0
- package/package.json +46 -4
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { queryTask } from '../services/api-client.js';
|
|
2
|
+
import { getTaskErrorInfo } from '../services/error-handler.js';
|
|
3
|
+
import { money, sleep, usdOf } from './shared.js';
|
|
4
|
+
/** Result links from the gateway stay downloadable for this long. */
|
|
5
|
+
export const RESULT_LINK_HOURS = 24;
|
|
6
|
+
/** Generation permission does not also authorize the assistant to alter the output. */
|
|
7
|
+
export const RESULT_DELIVERY_INSTRUCTIONS = [
|
|
8
|
+
'Deliver the original EvoLink result links immediately on completion, with clear view/download labels and the 24-hour expiry notice. Use delivery_markdown as the primary reply when supplied.',
|
|
9
|
+
'Do not delay delivery for inspection or post-processing. A generation request alone does not authorize local editing, compositing, repair or re-encoding; do that only when the user explicitly requests or authorizes post-processing.',
|
|
10
|
+
'Report quality issues and offer options. Keep the original links and label any authorized edited version separately.',
|
|
11
|
+
'Default to ordinary Markdown links for all media, including images; do not automatically add inline remote images or thumbnail placeholders. Only add an image preview when the user requests it and a supported working client preview route is available; otherwise keep the links.',
|
|
12
|
+
'The server may supply small embedded MCP image thumbnails or video cover frames alongside the original links. These optional previews are not edited replacements; let the client display them and keep delivery_markdown and the original download links in the reply. Do not turn preview metadata into remote Markdown images.',
|
|
13
|
+
'Use ordinary Markdown links for video/audio, never image syntax for a video URL. Inline previews depend on the client; do not promise them.',
|
|
14
|
+
].join(' ');
|
|
15
|
+
/** Compact tool description; the full contract is sent in server instructions and completed results. */
|
|
16
|
+
export const RESULT_DELIVERY_GUIDANCE = 'On completion, promptly deliver original links with the 24-hour expiry and delivery_markdown. Edit only when the user explicitly requests or authorizes post-processing. Keep original links alongside optional embedded MCP thumbnails; do not add remote-image Markdown or use image syntax for video/audio.';
|
|
17
|
+
export const TERMINAL_STATUSES = new Set(['completed', 'failed', 'cancelled']);
|
|
18
|
+
const MEDIA_EXTENSIONS = {
|
|
19
|
+
png: { kind: 'image', mimeType: 'image/png' },
|
|
20
|
+
jpg: { kind: 'image', mimeType: 'image/jpeg' },
|
|
21
|
+
jpeg: { kind: 'image', mimeType: 'image/jpeg' },
|
|
22
|
+
webp: { kind: 'image', mimeType: 'image/webp' },
|
|
23
|
+
gif: { kind: 'image', mimeType: 'image/gif' },
|
|
24
|
+
bmp: { kind: 'image', mimeType: 'image/bmp' },
|
|
25
|
+
mp4: { kind: 'video', mimeType: 'video/mp4' },
|
|
26
|
+
mov: { kind: 'video', mimeType: 'video/quicktime' },
|
|
27
|
+
webm: { kind: 'video', mimeType: 'video/webm' },
|
|
28
|
+
m4v: { kind: 'video', mimeType: 'video/x-m4v' },
|
|
29
|
+
mp3: { kind: 'audio', mimeType: 'audio/mpeg' },
|
|
30
|
+
wav: { kind: 'audio', mimeType: 'audio/wav' },
|
|
31
|
+
m4a: { kind: 'audio', mimeType: 'audio/mp4' },
|
|
32
|
+
flac: { kind: 'audio', mimeType: 'audio/flac' },
|
|
33
|
+
ogg: { kind: 'audio', mimeType: 'audio/ogg' },
|
|
34
|
+
aac: { kind: 'audio', mimeType: 'audio/aac' },
|
|
35
|
+
};
|
|
36
|
+
/** Infer metadata from the path only: a signed query or fragment is not a file extension. */
|
|
37
|
+
function mediaOfUrl(url) {
|
|
38
|
+
try {
|
|
39
|
+
const extension = /\.([a-z0-9]+)$/i.exec(new URL(url).pathname)?.[1].toLowerCase();
|
|
40
|
+
return extension && Object.prototype.hasOwnProperty.call(MEDIA_EXTENSIONS, extension) ? MEDIA_EXTENSIONS[extension] : undefined;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function kindOfUrl(url, taskType, hint) {
|
|
47
|
+
const media = mediaOfUrl(url);
|
|
48
|
+
if (media)
|
|
49
|
+
return media.kind;
|
|
50
|
+
if (hint)
|
|
51
|
+
return hint;
|
|
52
|
+
if (taskType.includes('image'))
|
|
53
|
+
return 'image';
|
|
54
|
+
if (taskType.includes('video'))
|
|
55
|
+
return 'video';
|
|
56
|
+
if (taskType.includes('audio') || taskType.includes('music'))
|
|
57
|
+
return 'audio';
|
|
58
|
+
return 'file';
|
|
59
|
+
}
|
|
60
|
+
export function resultLinks(task) {
|
|
61
|
+
const seen = new Set();
|
|
62
|
+
const links = [];
|
|
63
|
+
const add = (url, kind) => {
|
|
64
|
+
if (typeof url !== 'string' || !/^https?:\/\//.test(url) || seen.has(url))
|
|
65
|
+
return;
|
|
66
|
+
seen.add(url);
|
|
67
|
+
links.push({ url, kind: kindOfUrl(url, task.type ?? '', kind) });
|
|
68
|
+
};
|
|
69
|
+
for (const url of task.results ?? [])
|
|
70
|
+
add(url);
|
|
71
|
+
if (Array.isArray(task.result_data)) {
|
|
72
|
+
for (const item of task.result_data) {
|
|
73
|
+
add(item.video_url, 'video');
|
|
74
|
+
add(item.image_url, 'image');
|
|
75
|
+
add(item.audio_url, 'audio');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return links;
|
|
79
|
+
}
|
|
80
|
+
/** Typed links complement the text fallback; they do not guarantee a client preview.
|
|
81
|
+
* Never fetch or transform media here, and never wrap a video URL in ImageContent.
|
|
82
|
+
* Unknown extensions deliberately omit MIME instead of guessing a container.
|
|
83
|
+
*/
|
|
84
|
+
export function resultResources(taskId, links) {
|
|
85
|
+
return links.map((link, index) => {
|
|
86
|
+
const media = mediaOfUrl(link.url);
|
|
87
|
+
return {
|
|
88
|
+
type: 'resource_link',
|
|
89
|
+
uri: link.url,
|
|
90
|
+
name: `View/download original ${link.kind} ${index + 1} (${taskId})`,
|
|
91
|
+
description: `Original EvoLink generated ${link.kind}. View or download; result links expire after ${RESULT_LINK_HOURS} hours. Inline preview depends on the client.`,
|
|
92
|
+
...(media ? { mimeType: media.mimeType } : {}),
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/** A ready-to-send reply avoids triggering a client's remote-image fallback by default.
|
|
97
|
+
* Angle brackets keep parentheses in signed URLs inside the link destination.
|
|
98
|
+
* Resource URIs remain untouched; encode only characters unsafe in a Markdown destination.
|
|
99
|
+
*/
|
|
100
|
+
export function resultDeliveryMarkdown(taskId, links) {
|
|
101
|
+
return [
|
|
102
|
+
`EvoLink task ${taskId} completed.`,
|
|
103
|
+
...links.map((link, index) => {
|
|
104
|
+
const destination = link.url.replace(/[\u0000-\u0020<>\\]/g, char => encodeURIComponent(char));
|
|
105
|
+
return `[View/download original ${link.kind} ${index + 1}](<${destination}>)`;
|
|
106
|
+
}),
|
|
107
|
+
`Result links expire after ${RESULT_LINK_HOURS} hours; save them promptly.`,
|
|
108
|
+
].join('\n\n');
|
|
109
|
+
}
|
|
110
|
+
/** One task as text lines and the same facts as structured content. */
|
|
111
|
+
export function describeTask(task) {
|
|
112
|
+
const status = task.status ?? 'pending';
|
|
113
|
+
const links = resultLinks(task);
|
|
114
|
+
const lines = [
|
|
115
|
+
`Task ${task.id}: ${status}${status === 'completed' || status === 'failed' ? '' : ` (${task.progress ?? 0}%)`}`,
|
|
116
|
+
`Model: ${task.model}`,
|
|
117
|
+
];
|
|
118
|
+
const structured = {
|
|
119
|
+
task_id: task.id,
|
|
120
|
+
status,
|
|
121
|
+
progress: task.progress ?? 0,
|
|
122
|
+
model: task.model,
|
|
123
|
+
type: task.type,
|
|
124
|
+
};
|
|
125
|
+
if (links.length > 0) {
|
|
126
|
+
lines.push(`Results (download links expire after ${RESULT_LINK_HOURS} hours; save them now):`);
|
|
127
|
+
for (const link of links)
|
|
128
|
+
lines.push(`- ${link.kind}: ${link.url}`);
|
|
129
|
+
structured.results = links;
|
|
130
|
+
structured.links_expire_after_hours = RESULT_LINK_HOURS;
|
|
131
|
+
}
|
|
132
|
+
const used = task.usage?.credits_used ?? task.usage?.cost?.credits;
|
|
133
|
+
if (status === 'completed' && typeof used === 'number') {
|
|
134
|
+
lines.push(`Charged: ${money(used)}`);
|
|
135
|
+
structured.charged_credits = used;
|
|
136
|
+
structured.charged_usd = task.usage?.cost?.usd ?? usdOf(used);
|
|
137
|
+
}
|
|
138
|
+
const reserved = task.usage?.credits_reserved;
|
|
139
|
+
if (status !== 'completed' && status !== 'failed' && typeof reserved === 'number' && reserved > 0) {
|
|
140
|
+
lines.push(`Reserved: ${money(reserved)} (the final charge is settled when the task finishes)`);
|
|
141
|
+
structured.reserved_credits = reserved;
|
|
142
|
+
structured.reserved_usd = usdOf(reserved);
|
|
143
|
+
}
|
|
144
|
+
if (typeof task.duration === 'number' && task.duration > 0 && TERMINAL_STATUSES.has(status)) {
|
|
145
|
+
lines.push(`Took: ${task.duration} s`);
|
|
146
|
+
structured.took_seconds = task.duration;
|
|
147
|
+
}
|
|
148
|
+
if (status === 'failed' || status === 'cancelled') {
|
|
149
|
+
const code = task.error?.code ?? (status === 'cancelled' ? 'request_cancelled' : 'unknown_error');
|
|
150
|
+
const info = getTaskErrorInfo(code);
|
|
151
|
+
const suggestion = task.error?.suggestion ? `${info.suggestion} ${task.error.suggestion}` : info.suggestion;
|
|
152
|
+
lines.push(`Error: ${code}${task.error?.message ? ` — ${task.error.message}` : ''}`);
|
|
153
|
+
lines.push('Charge: failed tasks are refunded.');
|
|
154
|
+
lines.push(`Next step: ${info.retryable ? 'You can retry with a new generate call.' : 'Change the input before retrying.'} ${suggestion}`);
|
|
155
|
+
structured.error = { code, message: task.error?.message, retryable: info.retryable, suggestion };
|
|
156
|
+
structured.refunded = true;
|
|
157
|
+
}
|
|
158
|
+
else if (status === 'completed') {
|
|
159
|
+
if (links.length > 0) {
|
|
160
|
+
const delivery = resultDeliveryMarkdown(task.id, links);
|
|
161
|
+
structured.delivery_markdown = delivery;
|
|
162
|
+
lines.push(`Suggested reply (plain links; no automatic inline previews):\n${delivery}`);
|
|
163
|
+
}
|
|
164
|
+
lines.push(links.length > 0
|
|
165
|
+
? `Next step: ${RESULT_DELIVERY_INSTRUCTIONS}`
|
|
166
|
+
: 'Next step: the task completed but returned no result links. Tell the user; use get_task or list_tasks to recover them. Do not generate again automatically.');
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const eta = task.task_info?.estimated_time;
|
|
170
|
+
if (eta) {
|
|
171
|
+
lines.push(`Estimated time left: ~${eta} s`);
|
|
172
|
+
structured.estimated_seconds = eta;
|
|
173
|
+
}
|
|
174
|
+
lines.push(`Next step: call get_task with task_id "${task.id}" again (it can wait up to 45 s). Do not call generate again to check progress: that starts and charges a new task.`);
|
|
175
|
+
}
|
|
176
|
+
if (task.request_id) {
|
|
177
|
+
lines.push(`Request ID: ${task.request_id}`);
|
|
178
|
+
structured.request_id = task.request_id;
|
|
179
|
+
}
|
|
180
|
+
return { lines, structured, resources: resultResources(task.id, links) };
|
|
181
|
+
}
|
|
182
|
+
let pollIntervalOverrideMs;
|
|
183
|
+
/** Tests only: shorten the pause between task reads. */
|
|
184
|
+
export function setPollIntervalForTests(ms) {
|
|
185
|
+
pollIntervalOverrideMs = ms;
|
|
186
|
+
}
|
|
187
|
+
/** Pause between task reads: each read of an unfinished task makes the gateway ask the provider. */
|
|
188
|
+
export function pollIntervalMs(type) {
|
|
189
|
+
if (pollIntervalOverrideMs !== undefined)
|
|
190
|
+
return pollIntervalOverrideMs;
|
|
191
|
+
if (type?.includes('video'))
|
|
192
|
+
return 8_000;
|
|
193
|
+
if (type?.includes('audio') || type?.includes('music'))
|
|
194
|
+
return 6_000;
|
|
195
|
+
return 3_000;
|
|
196
|
+
}
|
|
197
|
+
/** Reads a task until it finishes or the deadline passes, pacing reads by task type. */
|
|
198
|
+
export async function waitForTask(config, taskId, options) {
|
|
199
|
+
let task = options.initial ?? await queryTask(config, taskId, options.tool);
|
|
200
|
+
while (!TERMINAL_STATUSES.has(task.status) && !options.signal?.aborted) {
|
|
201
|
+
const interval = pollIntervalMs(task.type);
|
|
202
|
+
if (Date.now() + interval > options.deadline)
|
|
203
|
+
break;
|
|
204
|
+
await options.onPoll?.(task);
|
|
205
|
+
await sleep(interval, options.signal);
|
|
206
|
+
if (options.signal?.aborted)
|
|
207
|
+
break;
|
|
208
|
+
task = await queryTask(config, taskId, options.tool);
|
|
209
|
+
}
|
|
210
|
+
return task;
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=task-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-format.js","sourceRoot":"","sources":["../../../../../core/src/tools/task-format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ServerConfig } from '../config.js';
|
|
3
|
+
export interface UploadFileOptions {
|
|
4
|
+
/** Allow file_path uploads. The hosted service sets false: it must never read its own disk. */
|
|
5
|
+
localFiles?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Signed-in hosted connection: no API key of its own, so each upload asks
|
|
8
|
+
* the gateway (config) for a short-lived upload token; base64_data is
|
|
9
|
+
* limited to 1 MB, larger local files go through prepare_upload.
|
|
10
|
+
*/
|
|
11
|
+
signedIn?: {
|
|
12
|
+
config: ServerConfig;
|
|
13
|
+
oneTimeUploads: boolean;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare function registerUploadFile(server: McpServer, options?: UploadFileOptions): void;
|
|
17
|
+
//# sourceMappingURL=upload-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-file.d.ts","sourceRoot":"","sources":["../../../../../core/src/tools/upload-file.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAuCjD,MAAM,WAAW,iBAAiB;IAChC,+FAA+F;IAC/F,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE;QAAE,MAAM,EAAE,YAAY,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;CAC9D;AAQD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,GAAE,iBAAsB,GAAG,IAAI,CA2G3F"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { requestUploadToken } from '../services/api-client.js';
|
|
4
|
+
import { fileStreamUpload, fileBase64Upload, fileUrlUpload } from '../services/file-client.js';
|
|
5
|
+
import { inspectBase64Upload, inspectLocalUpload, validateRemoteUploadURL, validateUploadDestination, } from '../services/upload-policy.js';
|
|
6
|
+
import { SIGNED_IN_BASE64_MAX_BYTES } from '../services/upload-slots.js';
|
|
7
|
+
import { WRITES, errorResult, failure, ok } from './shared.js';
|
|
8
|
+
const localFileSchema = {
|
|
9
|
+
file_path: z.string().optional()
|
|
10
|
+
.describe('Absolute path under EVOLINK_UPLOAD_ALLOWED_DIRS. Provide exactly one of file_path, base64_data, or file_url.'),
|
|
11
|
+
};
|
|
12
|
+
const contentSchema = {
|
|
13
|
+
base64_data: z.string().optional()
|
|
14
|
+
.describe('Base64 media data for small files. Data URLs carry their MIME type; raw base64 also needs mime_type.'),
|
|
15
|
+
mime_type: z.string().optional()
|
|
16
|
+
.describe('MIME type for raw base64_data; must match the file content.'),
|
|
17
|
+
file_url: z.string().optional()
|
|
18
|
+
.describe('Public HTTPS link to the media. Loopback, private-network and credential-bearing links are refused.'),
|
|
19
|
+
upload_path: z.string().optional()
|
|
20
|
+
.describe('Optional relative folder in EvoLink storage (no ..).'),
|
|
21
|
+
file_name: z.string().optional()
|
|
22
|
+
.describe('Optional plain file name (no folders).'),
|
|
23
|
+
};
|
|
24
|
+
const SHARED_DESCRIPTION = [
|
|
25
|
+
'Store an image, audio or video file on EvoLink and get a link to pass to generate_* (for example in image_urls). Free; uses the file quota, and files are deleted after 72 hours.',
|
|
26
|
+
'Formats: images JPEG, PNG, GIF, WebP; audio MP3, WAV, M4A, AAC, FLAC, OGG/Opus; video MP4, MOV, WebM.',
|
|
27
|
+
'Max 100 MB; prefer file_url for large files.',
|
|
28
|
+
];
|
|
29
|
+
export function registerUploadFile(server, options = {}) {
|
|
30
|
+
const localFiles = options.localFiles ?? true;
|
|
31
|
+
const signedIn = options.signedIn;
|
|
32
|
+
const sourceNames = localFiles ? 'file_path, base64_data, or file_url' : 'base64_data or file_url';
|
|
33
|
+
const largeFiles = signedIn?.oneTimeUploads
|
|
34
|
+
? 'for a local file over 1 MB call prepare_upload'
|
|
35
|
+
: 'pass a public file_url for anything larger';
|
|
36
|
+
/** Signed-in connections send an upload token from the gateway; everyone else sends their API key. */
|
|
37
|
+
async function withAuth(send) {
|
|
38
|
+
if (!signedIn)
|
|
39
|
+
return send();
|
|
40
|
+
const token = await requestUploadToken(signedIn.config, 'upload_file');
|
|
41
|
+
return send({ bearer: token.token });
|
|
42
|
+
}
|
|
43
|
+
const handler = async (params) => {
|
|
44
|
+
const { base64_data, file_url, mime_type, upload_path, file_name } = params;
|
|
45
|
+
const file_path = localFiles ? params.file_path : undefined;
|
|
46
|
+
const sources = [file_path, base64_data, file_url].filter(Boolean);
|
|
47
|
+
if (sources.length !== 1) {
|
|
48
|
+
const message = sources.length === 0 && signedIn
|
|
49
|
+
? `This hosted EvoLink connection cannot read files on the user's computer. Pass a public file_url, or base64_data for a file up to 1 MB; ${largeFiles}.`
|
|
50
|
+
: `Provide exactly one of ${sourceNames}.`;
|
|
51
|
+
return failure(message, { error: { category: 'invalid_request' } });
|
|
52
|
+
}
|
|
53
|
+
// Local checks first: a refused source never reaches the network.
|
|
54
|
+
let upload;
|
|
55
|
+
try {
|
|
56
|
+
validateUploadDestination(upload_path, file_name);
|
|
57
|
+
if (file_path) {
|
|
58
|
+
const inspected = await inspectLocalUpload(file_path);
|
|
59
|
+
upload = () => fileStreamUpload(inspected.realPath, inspected.size, inspected.mimeType, basename(inspected.realPath), upload_path, file_name);
|
|
60
|
+
}
|
|
61
|
+
else if (base64_data) {
|
|
62
|
+
const { dataUrl, decodedBytes } = inspectBase64Upload(base64_data, mime_type);
|
|
63
|
+
if (signedIn && decodedBytes > SIGNED_IN_BASE64_MAX_BYTES) {
|
|
64
|
+
throw new Error(`base64_data is limited to 1 MB on signed-in connections; ${largeFiles}`);
|
|
65
|
+
}
|
|
66
|
+
upload = () => withAuth(auth => fileBase64Upload(dataUrl, upload_path, file_name, auth));
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
const url = validateRemoteUploadURL(file_url);
|
|
70
|
+
upload = () => withAuth(auth => fileUrlUpload(url, upload_path, file_name, auth));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
const message = error instanceof Error ? error.message : 'the file was refused';
|
|
75
|
+
return failure(`Upload refused: ${message}`, { error: { category: 'invalid_request', message } });
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const result = await upload();
|
|
79
|
+
const data = result.data;
|
|
80
|
+
if (!data)
|
|
81
|
+
throw new Error('File API returned no upload record');
|
|
82
|
+
const lines = [
|
|
83
|
+
'File uploaded.',
|
|
84
|
+
`File URL: ${data.file_url}`,
|
|
85
|
+
`Name: ${data.original_name} · ${(data.file_size / 1024).toFixed(1)} KB · ${data.mime_type}`,
|
|
86
|
+
`Expires: ${data.expires_at}`,
|
|
87
|
+
];
|
|
88
|
+
if (result.request_id)
|
|
89
|
+
lines.push(`Request ID: ${result.request_id}`);
|
|
90
|
+
lines.push('Next step: pass the File URL to a generate tool as input.');
|
|
91
|
+
return ok(lines.join('\n'), {
|
|
92
|
+
file_url: data.file_url,
|
|
93
|
+
file_id: data.file_id,
|
|
94
|
+
file_name: data.original_name,
|
|
95
|
+
size_bytes: data.file_size,
|
|
96
|
+
mime_type: data.mime_type,
|
|
97
|
+
expires_at: data.expires_at,
|
|
98
|
+
...(result.request_id ? { request_id: result.request_id } : {}),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
return errorResult(error, { upload: true });
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
if (localFiles) {
|
|
106
|
+
server.registerTool('upload_file', {
|
|
107
|
+
title: 'Upload a file',
|
|
108
|
+
description: [...SHARED_DESCRIPTION, 'Local paths work only inside EVOLINK_UPLOAD_ALLOWED_DIRS.'].join(' '),
|
|
109
|
+
inputSchema: { ...localFileSchema, ...contentSchema },
|
|
110
|
+
annotations: { title: 'Upload a file', ...WRITES },
|
|
111
|
+
}, handler);
|
|
112
|
+
}
|
|
113
|
+
else if (signedIn) {
|
|
114
|
+
server.registerTool('upload_file', {
|
|
115
|
+
title: 'Upload a file',
|
|
116
|
+
description: [
|
|
117
|
+
SHARED_DESCRIPTION[0],
|
|
118
|
+
SHARED_DESCRIPTION[1],
|
|
119
|
+
`Accepts a public file_url, or base64_data of a small file up to 1 MB. This service cannot read files on the user's computer: ${largeFiles}.`,
|
|
120
|
+
].join(' '),
|
|
121
|
+
inputSchema: contentSchema,
|
|
122
|
+
annotations: { title: 'Upload a file', ...WRITES },
|
|
123
|
+
}, handler);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
server.registerTool('upload_file', {
|
|
127
|
+
title: 'Upload a file',
|
|
128
|
+
description: [...SHARED_DESCRIPTION, 'Accepts base64_data or a public file_url.'].join(' '),
|
|
129
|
+
inputSchema: contentSchema,
|
|
130
|
+
annotations: { title: 'Upload a file', ...WRITES },
|
|
131
|
+
}, handler);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=upload-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-file.js","sourceRoot":"","sources":["../../../../../core/src/tools/upload-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../../core/src/version.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,eAAO,MAAM,WAAW,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../../core/src/version.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { createServer, createConfig, getApiKey } from '../../core/src/server.js';
|
|
4
|
+
import { setProcessLinkCampaign } from '../../core/src/request-context.js';
|
|
5
|
+
async function main() {
|
|
6
|
+
setProcessLinkCampaign('mcp_local'); // site links from the npm package: utm_campaign=mcp_local
|
|
7
|
+
getApiKey(); // validate API key early
|
|
8
|
+
const config = createConfig('official');
|
|
9
|
+
const server = createServer(config);
|
|
10
|
+
const transport = new StdioServerTransport();
|
|
11
|
+
await server.connect(transport);
|
|
12
|
+
console.error('EvoLink Media MCP Server (official) started');
|
|
13
|
+
}
|
|
14
|
+
main().catch((err) => {
|
|
15
|
+
console.error('Fatal error:', err);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAE3E,KAAK,UAAU,IAAI;IACjB,sBAAsB,CAAC,WAAW,CAAC,CAAC,CAAC,0DAA0D;IAC/F,SAAS,EAAE,CAAC,CAAC,yBAAyB;IAEtC,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;AAC/D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evolinkai/mcp",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
6
|
-
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"mcpName": "ai.evolink/mcp",
|
|
5
|
+
"description": "Generate AI videos, images & music with one API key. 150+ models (Seedance, Kling, Veo, Sora, GPT Image, Suno...).",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/evolink-media/src/index.js",
|
|
8
|
+
"bin": {
|
|
9
|
+
"evolink-mcp": "dist/evolink-media/src/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"prepack": "node -e \"require('fs').copyFileSync('../../LICENSE','LICENSE')\"",
|
|
17
|
+
"postpack": "node -e \"require('fs').rmSync('LICENSE',{force:true})\""
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"claude",
|
|
22
|
+
"ai",
|
|
23
|
+
"video",
|
|
24
|
+
"image",
|
|
25
|
+
"music",
|
|
26
|
+
"generation",
|
|
27
|
+
"sora",
|
|
28
|
+
"suno",
|
|
29
|
+
"kling",
|
|
30
|
+
"veo",
|
|
31
|
+
"seedance"
|
|
32
|
+
],
|
|
33
|
+
"author": "EvoLink AI <support@evolink.ai>",
|
|
34
|
+
"license": "Apache-2.0",
|
|
35
|
+
"homepage": "https://evolink.ai/mcp",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/Evolink-AI/evolink-mcp.git"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.32.0",
|
|
42
|
+
"zod": "^3.24.2"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^22.13.4",
|
|
46
|
+
"typescript": "^5.7.3"
|
|
47
|
+
}
|
|
48
|
+
}
|