@vidofy/mcp 0.1.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 +21 -0
- package/README.md +151 -0
- package/dist/backend.d.ts +133 -0
- package/dist/backend.js +455 -0
- package/dist/config.d.ts +85 -0
- package/dist/config.js +207 -0
- package/dist/heartbeat.d.ts +11 -0
- package/dist/heartbeat.js +70 -0
- package/dist/http.d.ts +44 -0
- package/dist/http.js +885 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.js +661 -0
- package/dist/log.d.ts +19 -0
- package/dist/log.js +22 -0
- package/dist/map/b2c.d.ts +139 -0
- package/dist/map/b2c.js +236 -0
- package/dist/media-duration.d.ts +33 -0
- package/dist/media-duration.js +137 -0
- package/dist/oauth/authorize.d.ts +61 -0
- package/dist/oauth/authorize.js +275 -0
- package/dist/oauth/clients.d.ts +137 -0
- package/dist/oauth/clients.js +621 -0
- package/dist/oauth/ratelimit.d.ts +92 -0
- package/dist/oauth/ratelimit.js +116 -0
- package/dist/oauth/store.d.ts +135 -0
- package/dist/oauth/store.js +277 -0
- package/dist/oauth/token.d.ts +29 -0
- package/dist/oauth/token.js +165 -0
- package/dist/schema.d.ts +147 -0
- package/dist/schema.js +629 -0
- package/dist/tools/account.d.ts +28 -0
- package/dist/tools/account.js +130 -0
- package/dist/tools/generation.d.ts +102 -0
- package/dist/tools/generation.js +1194 -0
- package/dist/tools/info.d.ts +50 -0
- package/dist/tools/info.js +95 -0
- package/dist/ui/generation-card.html +869 -0
- package/package.json +79 -0
- package/server.json +36 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Account tools — what the balance is, and where it went.
|
|
3
|
+
*
|
|
4
|
+
* Both read-only. Neither can move money: the endpoints that could (checkout,
|
|
5
|
+
* auto-topup, purchases) are deliberately not exposed by this package at all,
|
|
6
|
+
* so an agent cannot buy coins on the user's behalf however it is prompted.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import { request } from '../backend.js';
|
|
10
|
+
import { stripProviderCost } from '../map/b2c.js';
|
|
11
|
+
const rec = (v) => v !== null && typeof v === 'object' && !Array.isArray(v) ? v : {};
|
|
12
|
+
const int = (v) => {
|
|
13
|
+
const n = typeof v === 'number' ? v : typeof v === 'string' && v !== '' ? Number(v) : NaN;
|
|
14
|
+
return Number.isFinite(n) ? n : null;
|
|
15
|
+
};
|
|
16
|
+
const str = (v) => {
|
|
17
|
+
if (v === null || v === undefined)
|
|
18
|
+
return null;
|
|
19
|
+
const s = String(v);
|
|
20
|
+
return s === '' ? null : s;
|
|
21
|
+
};
|
|
22
|
+
/* ── get_balance ─────────────────────────────────────────────────────────── */
|
|
23
|
+
export async function getBalance(cfg) {
|
|
24
|
+
const payload = await request(cfg, { method: 'GET', path: 'account/balance' });
|
|
25
|
+
const d = rec(rec(payload)['data']);
|
|
26
|
+
if (cfg.mode === 'key') {
|
|
27
|
+
/* Unreachable in practice — index.ts registers no tools in key mode, so
|
|
28
|
+
* nothing can call this. Kept as a belt-and-braces answer in case a
|
|
29
|
+
* future refactor registers the tools before checking the mode, and
|
|
30
|
+
* worded like the startup refusal so the two cannot tell a user
|
|
31
|
+
* different stories. Not a stub awaiting a phase: the server is for
|
|
32
|
+
* personal accounts by decision (2026-09-11). */
|
|
33
|
+
return {
|
|
34
|
+
unit: 'credits',
|
|
35
|
+
note: 'This server serves personal Vidofy accounts only, and reports the '
|
|
36
|
+
+ 'coin balance of the account whose token it holds.',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const sub = rec(d['active_subscription']);
|
|
40
|
+
const expiring = int(d['u_coins_expiring']) ?? 0;
|
|
41
|
+
return {
|
|
42
|
+
coins: int(d['u_coins']),
|
|
43
|
+
unit: 'coins',
|
|
44
|
+
/* Two numbers, because they answer different questions. Coins from a
|
|
45
|
+
subscription expire when the cycle ends; bought or earned coins do
|
|
46
|
+
not. An agent that reports only the total will tell someone they have
|
|
47
|
+
plenty on the day most of it disappears. */
|
|
48
|
+
coins_permanent: int(d['coins_permanent']),
|
|
49
|
+
coins_expiring: expiring,
|
|
50
|
+
coins_expire_at: expiring > 0 ? str(d['coins_expire_at']) : null,
|
|
51
|
+
subscription: str(d['active_subscription']) === null && Object.keys(sub).length === 0
|
|
52
|
+
? null
|
|
53
|
+
: {
|
|
54
|
+
plan: str(sub['plan_name']),
|
|
55
|
+
status: str(sub['status']),
|
|
56
|
+
renews_or_ends: str(sub['expires_at']),
|
|
57
|
+
cancel_at_period_end: sub['cancel_at_period_end'] === true,
|
|
58
|
+
},
|
|
59
|
+
account_status: str(d['u_status']),
|
|
60
|
+
email: str(d['u_email']),
|
|
61
|
+
/* Not a hint the agent can act on inside this server — nothing here
|
|
62
|
+
can buy coins. It exists so a "you are out of coins" answer can tell
|
|
63
|
+
the user where to go. */
|
|
64
|
+
top_up_url: 'https://vidofy.ai/en/pricing',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/* ── get_usage ───────────────────────────────────────────────────────────── */
|
|
68
|
+
export const getUsageInput = z.object({
|
|
69
|
+
days: z
|
|
70
|
+
.number()
|
|
71
|
+
.int()
|
|
72
|
+
.min(1)
|
|
73
|
+
.max(365)
|
|
74
|
+
.optional()
|
|
75
|
+
.describe('How many days back to look. Default 30.'),
|
|
76
|
+
limit: z.number().int().min(1).max(100).optional().describe('Rows to return. Default 20.'),
|
|
77
|
+
offset: z.number().int().min(0).optional().describe('Rows to skip, for paging.'),
|
|
78
|
+
});
|
|
79
|
+
export async function getUsage(cfg, args) {
|
|
80
|
+
const payload = await request(cfg, {
|
|
81
|
+
method: 'GET',
|
|
82
|
+
path: 'account/usage',
|
|
83
|
+
query: { days: args.days, limit: args.limit, offset: args.offset },
|
|
84
|
+
});
|
|
85
|
+
// Every field below has already been through the strip: usage carries
|
|
86
|
+
// aul_api_cost per row and total_api_cost in the summary, both of which are
|
|
87
|
+
// what Vidofy pays its providers.
|
|
88
|
+
const root = rec(stripProviderCost(payload));
|
|
89
|
+
const d = rec(root['data']);
|
|
90
|
+
const summary = rec(d['summary']);
|
|
91
|
+
const filters = rec(d['filters']);
|
|
92
|
+
const items = Array.isArray(d['items']) ? d['items'] : [];
|
|
93
|
+
return {
|
|
94
|
+
window_days: int(filters['days']) ?? 30,
|
|
95
|
+
unit: cfg.mode === 'account' ? 'coins' : 'credits',
|
|
96
|
+
summary: {
|
|
97
|
+
requests: int(summary['total_requests']),
|
|
98
|
+
succeeded: int(summary['success_requests']),
|
|
99
|
+
failed: int(summary['failed_requests']),
|
|
100
|
+
still_running: int(summary['processing_requests']),
|
|
101
|
+
spent: int(summary['total_coins_charged']) ?? int(summary['total_api_credits_charged']),
|
|
102
|
+
},
|
|
103
|
+
// `requests` above is a count over the whole window, not the size of
|
|
104
|
+
// this page — so paging with offset is meaningful.
|
|
105
|
+
items: items.map((raw) => {
|
|
106
|
+
const r = rec(raw);
|
|
107
|
+
return {
|
|
108
|
+
/* aul_request_uid FIRST, and it is not a stylistic preference.
|
|
109
|
+
*
|
|
110
|
+
* The B2C usage endpoint renames its columns to the aul_* names
|
|
111
|
+
* for old mobile builds, and in doing so it exposes TWO ids:
|
|
112
|
+
* `media_id` is an internal integer key, `aul_request_uid` is
|
|
113
|
+
* the 25-character m_id. get_status and get_result look up by
|
|
114
|
+
* m_id, so
|
|
115
|
+
* returning the integer gives the agent an id that 404s on the
|
|
116
|
+
* very next call. Caught in adversarial review 2026-09-07;
|
|
117
|
+
* the fixture account has no usage rows, so no test had ever
|
|
118
|
+
* seen this mapping run on data. */
|
|
119
|
+
id: str(r['aul_request_uid']) ?? str(r['m_id']) ?? str(r['media_id']),
|
|
120
|
+
at: str(r['aul_created_at']) ?? str(r['created_at']) ?? str(r['m_time']),
|
|
121
|
+
mode: str(r['aul_mode']) ?? str(r['m_mode']),
|
|
122
|
+
model: str(r['aul_model_key']) ?? str(r['m_model_key']) ?? str(r['m_name']),
|
|
123
|
+
status: str(r['aul_status']) ?? str(r['m_status']),
|
|
124
|
+
spent: int(r['aul_coins_charged']) ?? int(r['m_coins']),
|
|
125
|
+
error: str(r['aul_error_message']) ?? str(r['m_api_error']),
|
|
126
|
+
};
|
|
127
|
+
}),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run a generation, price one first, and read one back.
|
|
3
|
+
*
|
|
4
|
+
* `generate` is the only tool in this package that spends anything. Everything
|
|
5
|
+
* around it is read-only.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import type { Config } from '../config.js';
|
|
9
|
+
import { stripProviderCost } from '../map/b2c.js';
|
|
10
|
+
export declare const estimateCostInput: z.ZodObject<{
|
|
11
|
+
model: z.ZodString;
|
|
12
|
+
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
13
|
+
}, "strip", z.ZodTypeAny, {
|
|
14
|
+
model: string;
|
|
15
|
+
input?: Record<string, unknown> | undefined;
|
|
16
|
+
}, {
|
|
17
|
+
model: string;
|
|
18
|
+
input?: Record<string, unknown> | undefined;
|
|
19
|
+
}>;
|
|
20
|
+
/**
|
|
21
|
+
* Ask the server what a generation would cost, before running it.
|
|
22
|
+
*
|
|
23
|
+
* The price is computed by the same calculator the submit path uses, so this
|
|
24
|
+
* is an answer rather than an estimate — provided the input matches what
|
|
25
|
+
* generate will be given.
|
|
26
|
+
*/
|
|
27
|
+
export declare function estimateCost(cfg: Config, args: {
|
|
28
|
+
model: string;
|
|
29
|
+
input?: Record<string, unknown> | undefined;
|
|
30
|
+
}): Promise<unknown>;
|
|
31
|
+
export declare const generateInput: z.ZodObject<{
|
|
32
|
+
model: z.ZodString;
|
|
33
|
+
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
34
|
+
public: z.ZodOptional<z.ZodBoolean>;
|
|
35
|
+
}, "strip", z.ZodTypeAny, {
|
|
36
|
+
model: string;
|
|
37
|
+
input: Record<string, unknown>;
|
|
38
|
+
public?: boolean | undefined;
|
|
39
|
+
}, {
|
|
40
|
+
model: string;
|
|
41
|
+
input: Record<string, unknown>;
|
|
42
|
+
public?: boolean | undefined;
|
|
43
|
+
}>;
|
|
44
|
+
export declare function generate(cfg: Config, args: {
|
|
45
|
+
model: string;
|
|
46
|
+
input: Record<string, unknown>;
|
|
47
|
+
public?: boolean | undefined;
|
|
48
|
+
}, ctx?: {
|
|
49
|
+
signal?: AbortSignal;
|
|
50
|
+
}): Promise<unknown>;
|
|
51
|
+
export declare const generationIdInput: z.ZodObject<{
|
|
52
|
+
id: z.ZodString;
|
|
53
|
+
}, "strip", z.ZodTypeAny, {
|
|
54
|
+
id: string;
|
|
55
|
+
}, {
|
|
56
|
+
id: string;
|
|
57
|
+
}>;
|
|
58
|
+
/** get_result takes the same id, plus a way to decline the inline image. */
|
|
59
|
+
export declare const generationResultInput: z.ZodObject<{
|
|
60
|
+
id: z.ZodString;
|
|
61
|
+
} & {
|
|
62
|
+
include_preview: z.ZodOptional<z.ZodBoolean>;
|
|
63
|
+
}, "strip", z.ZodTypeAny, {
|
|
64
|
+
id: string;
|
|
65
|
+
include_preview?: boolean | undefined;
|
|
66
|
+
}, {
|
|
67
|
+
id: string;
|
|
68
|
+
include_preview?: boolean | undefined;
|
|
69
|
+
}>;
|
|
70
|
+
export declare function getStatus(cfg: Config, args: {
|
|
71
|
+
id: string;
|
|
72
|
+
}): Promise<unknown>;
|
|
73
|
+
export declare function getResult(cfg: Config, args: {
|
|
74
|
+
id: string;
|
|
75
|
+
include_preview?: boolean | undefined;
|
|
76
|
+
}): Promise<unknown>;
|
|
77
|
+
/** Attach media to a result. @see takePreview */
|
|
78
|
+
export declare function setPreview(result: object, preview: {
|
|
79
|
+
data: string;
|
|
80
|
+
mimeType: string;
|
|
81
|
+
}): void;
|
|
82
|
+
/** The media attached to a result, if any. Read once by the dispatcher. */
|
|
83
|
+
export declare function takePreview(result: unknown): {
|
|
84
|
+
data: string;
|
|
85
|
+
mimeType: string;
|
|
86
|
+
} | null;
|
|
87
|
+
/**
|
|
88
|
+
* One reading of a generation, shaped for the card view.
|
|
89
|
+
*
|
|
90
|
+
* Called by the view through the host, never by the model — the tool is
|
|
91
|
+
* registered app-only. So it may be called every few seconds without costing
|
|
92
|
+
* tokens or filling the transcript, and it must stay cheap: one request while
|
|
93
|
+
* the job runs, two once it finishes.
|
|
94
|
+
*
|
|
95
|
+
* Status carries the progress; only a finished job needs the result, and only
|
|
96
|
+
* then does the second call happen.
|
|
97
|
+
*/
|
|
98
|
+
export declare function cardState(cfg: Config, args: {
|
|
99
|
+
id: string;
|
|
100
|
+
}): Promise<unknown>;
|
|
101
|
+
/** Exported for the gate, which asserts nothing costed ever escapes. */
|
|
102
|
+
export { stripProviderCost };
|